RawInputで複数のマウスからの入力を取得する

RawInputの勉強。ようやく二つのマウスからの入力を取得できるようになった。
まずは初期化。

#define WINVER (0x500)        // RawInput用
#define _WIN32_WINNT (0x0501) // RawInput用
#include <windows.h>void init()
{
  // 現在接続されている入力デバイスの数を取得
  UINT deviceNum = 0;
  GetRawInputDeviceList(NULL, &deviceNum, sizeof(RAWINPUTDEVICELIST));

  // デバイス情報用構造体
  RAWINPUTDEVICELIST* deviceList = new RAWINPUTDEVICELIST[deviceNum];

  // デバイス情報の取得
  if (GetRawInputDeviceList(deviceList, &deviceNum, sizeof(RAWINPUTDEVICELIST)) != deviceNum)
  { 
    // エラー
  } 

  delete[] deviceList;

"deviceList[i].hDevice"にデバイスのハンドルが入っているので、入力が欲しいデバイスのハンドルを保存しておく。
(・・・この処理は改良の余地あり。)

次にプロシージャのWM_INPUTから入力を取得できるように登録。

  // WM_INPUTで受け取れるように登録
  RAWINPUTDEVICE device[1];
  device[0].usUsagePage = 0x01;	// マウス用の定数
  device[0].usUsage = 0x02;		// マウス用の定数
  device[0].dwFlags = 0;
  device[0].hwndTarget = g_hWnd;
 
  if (RegisterRawInputDevices(device, 1, sizeof(device[0])) == 0)
  {
     // エラー
  }
}

取得。
今回はとりあえずグローバル変数でやり取りしてみる。

// グローバル変数
RAWINPUTHEADER g_header[2];
RAWMOUSE g_mouseInfo[2];

…

LRESULT CALLBACK mainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
  case WM_INPUT:
  {
    UINT dwSize;
      
      GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
      unsigned char* lpb = new unsigned char[dwSize];
      if (lpb == NULL)
      {
        // エラー
        return 0;
      }

      if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize)
      {
        // エラー
      }

      RAWINPUT* raw = (RAWINPUT*)lpb;

      if (raw->header.dwType == RIM_TYPEMOUSE) 
      {
        if ((u_int)raw->header.hDevice == g_deviceID[0])
        {
          g_mouseInfo[0] = raw->data.mouse;
          g_header[0] = raw->header;
        }
        else if ((u_int)raw->header.hDevice == g_deviceID[1])
        {
          g_mouseInfo[1] = raw->data.mouse;
          g_header[1] = raw->header;
        }
      }

      delete[] lpb; 
    }
    break;
  }

    …

  return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}

あとはg_mouseInfo[i]内にデータが入るので、それを使えばOK。
二個のマウスを同時に動かしたときは、WM_INPUTに二回メッセージが送られてくる。

実装はできたけど、やや強引に作ったので内容もコードも微妙になってしまった。
修正しなくては。


↓とりあえず作成したサンプル

そのうちキーボード二個にも対応させてみよう。


※参考にさせていただきました。
http://www.kedm.bosai.go.jp/project/info-share/report/H17/H17_4-6-2.pdf
http://members.jcom.home.ne.jp/toya.hiroshi/ui/usingrawinput.html#buffered_read