マウスの情報を取得

Page creation date :

The page you are currently viewing does not support the selected display language.

今回は DirectInput を使用してマウスの情報を取得します。といってもキーボードとそんなに違いは無いと思います。

マウスの情報を取得

今回のメインコードファイルを載せます。部分的な説明に関してはコードの下の方で説明しています。

MainSample.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.DirectInput;

namespace MDXSample
{
    /// <summary>
    /// メインサンプルクラス
    /// </summary>
    public class MainSample : IDisposable
    {
        /// <summary>
        /// メインフォーム
        /// </summary>
        private MainForm _form = null;

        /// <summary>
        /// マウスデバイス
        /// </summary>
        private Device _mouseDevice = null;


        /// <summary>
        /// アプリケーションの初期化
        /// </summary>
        /// <param name="topLevelForm">トップレベルウインドウ</param>
        /// <returns>全ての初期化がOKなら true, ひとつでも失敗したら false を返すようにする</returns>
        /// <remarks>
        /// false を返した場合は、自動的にアプリケーションが終了するようになっている
        /// </remarks>
        public bool InitializeApplication(MainForm topLevelForm)
        {
            // フォームの参照を保持
            this._form = topLevelForm;

            // マウスデバイスの初期化
            try
            {
                // マウスデバイスの作成
                this._mouseDevice = new Device(SystemGuid.Mouse);

                // 協調レベルの設定
                this._mouseDevice.SetCooperativeLevel(topLevelForm,
                    CooperativeLevelFlags.NonExclusive | CooperativeLevelFlags.Background);
            }
            catch (DirectXException ex)
            {
                MessageBox.Show(ex.ToString(), "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            try
            {
                // キャプチャするデバイスを取得
                this._mouseDevice.Acquire();
            }
            catch (DirectXException)
            {
            }

            return true;
        }

        /// <summary>
        /// メインループ処理
        /// </summary>
        public void MainLoop()
        {
            MouseState state;
            try
            {
                // マウスの状態をキャプチャ
                state = this._mouseDevice.CurrentMouseState;
            }
            catch (DirectXException)
            {
                try
                {
                    // キャプチャするデバイスを取得
                    this._mouseDevice.Acquire();

                    // マウスの状態をキャプチャ
                    state = this._mouseDevice.CurrentMouseState;
                }
                catch (DirectXException)
                {
                    return;
                }
            }

            StringBuilder builder = new StringBuilder();

            // キャプチャ位置
            builder.Append("X:" + state.X + Environment.NewLine);
            builder.Append("Y:" + state.Y + Environment.NewLine);
            builder.Append("Z:" + state.Z + Environment.NewLine);

            // キャプチャボタン
            byte[] buttons = state.GetMouseButtons();
            for (int i = 0; i < buttons.Length; i++)
            {
                if (buttons[i] != 0)
                {
                    builder.Append("Button:" + i + Environment.NewLine);
                }
            }

            // ラベルに表示
            this._form.InputLabel.Text = builder.ToString();
        }

        /// <summary>
        /// リソースの破棄をするために呼ばれる
        /// </summary>
        public void Dispose()
        {
            // マウスデバイスの解放
            if (this._mouseDevice != null)
            {
                this._mouseDevice.Dispose();
            }
        }
    }
}

では、赤文字の部分を説明していきます。


/// <summary>
/// マウスデバイス
/// </summary>
private Device _mouseDevice = null

マウスの場合も、キーボードと同じように Device クラスを使用します。


// マウスデバイスの初期化
try
{
    // マウスデバイスの作成
    this._mouseDevice = new Device(SystemGuid.Mouse);

    // 協調レベルの設定
    this._mouseDevice.SetCooperativeLevel(topLevelForm,
        CooperativeLevelFlags.NonExclusive | CooperativeLevelFlags.Background);
}
catch (DirectXException ex)
{
    MessageBox.Show((ex.ToString(), "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
    return false;
}

デバイスの作成もキーボードの時とほとんど同じです。Device を作成するときにマウスの GUID を指定します。


try
{
    // キャプチャするデバイスを取得
    this._mouseDevice.Acquire();
}
catch (DirectXException)
{
}

キャプチャするデバイスの取得を試みます。ここで取得できなかった場合はメインループで取得します。


MouseState state;
try
{
    // マウスの状態をキャプチャ
    state = this._mouseDevice.CurrentMouseState;
}
catch (DirectXException)
{
    try
    {
        // キャプチャするデバイスを取得
        this._mouseDevice.Acquire();

        // マウスの状態をキャプチャ
        state = this._mouseDevice.CurrentMouseState;
    }
    catch (DirectXException)
    {
        return;
    }
}

メインループではマウスの状態を取得するために「Device.CurrentMouseState」から情報を受け取るようにしています。もちろんデバイスが取得できる状態でないと例外が発生するので、デバイスを受け取れるように対応しています。


StringBuilder builder = new StringBuilder();

// キャプチャ位置
builder.Append("X:" + state.X + Environment.NewLine);
builder.Append("Y:" + state.Y + Environment.NewLine);
builder.Append("Z:" + state.Z + Environment.NewLine);

マウスの位置情報は「MouseState.X」などで取得することが出来ます。ただし、ここで受け取れる値は、前回マウスの状態を取得したときからの相対位置です。もし、絶対位置を取得したい場合は、事前に「Device.Properties.AxisModeAbsolute」を true に設定して絶対軸モードにしておかなければいけません。ただし、ここで言う絶対位置とは、スクリーン座標とかフォームのクライアント座標とは別なので注意してください。


// キャプチャボタンです
byte[] buttons = state.GetMouseButtons();
for (int i = 0; i < buttons.Length; i++)
{
    if (buttons[i] != 0)
    {
        builder.Append("Button:" + i + Environment.NewLine);
    }
} 

// ラベルに表示
this._form.InputLabel.Text = builder.ToString();

マウスのボタン情報は「MouseState.GetMouseButtons」メソッドで取得することが出来ます。マウスのボタンは最大8個取得でき、押されていないときは「0x00」押されているときは「0x80」の値が格納されます。


// マウスデバイスの解放
if (this._mouseDevice != null)
{
    this._mouseDevice.Dispose();
}

最後にマウスのデバイスを解放しています。