Windowsで手軽にタッチパネルの情報にアクセスできないだろうか?
タッチパネルといえばWindows 8だが、実はWindows 7から正式に対応をしているのだ。
(それ以前は、デジタイザという扱い)
WindowsではUI入力は十把一絡げにHID(Human Interface Device)クラスとして取り扱われている。
キーボードもマウスも、タッチパネルも皆HIDだ。
まずはMFCでWM_INPUTメッセージを利用してRAWINPUTを取得してみる。
https://msdn.microsoft.com/en-us/library/windows/desktop/ms645590(v=vs.85).aspx
Visual StudioでMFCのダイアログベースのスケルトンを作成する
名前は適当に付ける(ここでは"MFCAho")。
WM_INPUTで受けるデバイスを登録する
DialogクラスのOnInitDialogに以下を追加する。
RAWINPUTDEVICE ridTest[1]; // for touch ridTest[0].usUsagePage = 0x0d; ridTest[0].usUsage = 0x00; ridTest[0].dwFlags = RIDEV_INPUTSINK | RIDEV_PAGEONLY; ridTest[0].hwndTarget = m_hWnd; // RegisterRawInputDevices(ridTest, 1, sizeof(RAWINPUTDEVICE));
今回はタッチの入力を拾うことが目的なので、タッチデバイスのみを登録している。
マウスやキーボードもここで登録すれば、マウスやキーボード入力があったときに以下のイベントハンドラで拾ってくれる。
RegisterRawInputDevicesの詳細は以下。
https://msdn.microsoft.com/en-us/library/windows/desktop/ms645600(v=vs.85).aspx
ここで出てくるusUsagePageとusUsageはHIDの仕様に従っている。
http://www.usb.org/developers/hidpage/Hut1_12v2.pdf
Class Wizardを開き、ダイアログのクラスを選択し、"Messages"から"WM_INPUT"を選びそのイベントハンドラ(OnRawInput)を追加する
イベントハンドラの実装は以下の通り
void CMFCAhoDlg::OnRawInput(UINT nInputcode, HRAWINPUT hRawInput) { // This feature requires Windows XP or greater. // The symbol _WIN32_WINNT must be >= 0x0501. // TODO: Add your message handler code here and/or call default UINT size; RAWINPUT* pRI = NULL; GetRawInputData( hRawInput, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER) ); if (size != 0) { unsigned char* buffer = new unsigned char[size]; pRI = (RAWINPUT*)buffer; GetRawInputData( hRawInput, RID_INPUT, pRI, &size, sizeof(RAWINPUTHEADER) ); printRAWINPUT(pRI); Invalidate(); delete[] buffer; } // CDialogEx::OnRawInput(nInputcode, hRawInput); }
GetRawInputDataの詳細は以下。
https://msdn.microsoft.com/en-us/library/windows/desktop/ms645596(v=vs.85).aspx
ここでのポイントは、GetRawInputDataを2回呼ぶ必要があることだ。
一度目でサイズを取得し、その後バッファーを準備して、二回目でRAWINPUT構造体を取得する。
取得したRAWINPUT構造体をパースする
RAWINPUT構造体の詳細は以下。
https://msdn.microsoft.com/ja-jp/library/windows/desktop/ms645562(v=vs.85).aspx
typedef struct tagRAWINPUT { RAWINPUTHEADER header; union { RAWMOUSE mouse; RAWKEYBOARD keyboard; RAWHID hid; } data; } RAWINPUT, *PRAWINPUT, *LPRAWINPUT;
中にはRAWINPUTHEADER、RAWMOUSE、RAWKEYBOARD、RAWHIDが含まれる。
RAWINPUTHEADER.dwTypeでマウス、キーボード、もしくはそれ以外のHIDが入力されたかがわかる。
https://msdn.microsoft.com/ja-jp/library/windows/desktop/ms645571(v=vs.85).aspx
なので、こんな感じで受ける。
void CMFCAhoDlg::parseRAWINPUT(RAWINPUT* pRAWINPUT) { RAWINPUTHEADER RawInputHeader = pRAWINPUT->header; RAWMOUSE RawMouse = pRAWINPUT->data.mouse; RAWKEYBOARD RawKeyboard = pRAWINPUT->data.keyboard; RAWHID RawHID = pRAWINPUT->data.hid; // if (RawInputHeader.dwType == RIM_TYPEHID) { for (int count = 0; count < RawHID.dwSizeHid * RawHID.dwCount; count++) { // ここでRawHIDの処理をする } } }
しめしめ、これでまんまとタッチパネルの情報が入手できるぞ。
うんしょうんしょ・・・
あれ、なんかそれっぽいデータが出てこない。
どうもレイヤードライバがすでにいじくり倒した後のようだ。
ということで、To Be Continued