通常我们运用钩子(hook)捕获消息,其实windows还给我们提供了其他方法捕获系统设备消息。
今天我们就利用RegisterRawInputDevices 来捕获设备消息。
以Win32程序为例: 首先注册设备RegisterRawInputDevices, 然后在消息循环中 添加WM_INPUT 的消息处理函数, 用GetRawInputData转换参数。
注册设备
先要包含头文件Winuser.h 和 动态库User32.lib。
RegisterRawInputDevices函数说明:
BOOL WINAPI RegisterRawInputDevices(
_In_ PCRAWINPUTDEVICE pRawInputDevices, //设备信息数组,可包含多种设备
_In_ UINT uiNumDevices, //pRawInputDevices数组 的大小,即设备种类
_In_ UINT cbSize //sizeof(RAWINPUTDEVICE)
);
现在对RAWINPUTDEVICE结构体进行简单说明:
typedef struct tagRAWINPUTDEVICE {
USHORT usUsagePage; //usUsagePage 和 usUsage 确定设备种类
USHORT usUsage;
DWORD dwFlags; //指定发送消息的方式
HWND hwndTarget; //接受WM_INPUT消息的窗口句柄,如果是NULL,接受消息窗口就跟随键盘焦点
} RAWINPUTDEVICE, *PRAWINPUTDEVICE, *LPRAWINPUTDEVICE;
dwFlags 用很多种标志,这里通常用的是RIDEV_INPUTSINK, 表示不论接受窗口是否获得焦点,设备消息都发送给该窗口。这种情况hwndTarget必须指定。
鼠标标志为:usUsagePage = 0x01, usUsage=0x02.
键盘标志位:usUsagePage = 0x01, usUsage=0x06.
示范:
BOOL RegisitKeyBord(HWND hwnd)
{
if (NULL == hwnd)
return false
RAWINPUTDEVICE rid; //设备信息
rid.usUsagePage = 0x01;
rid.usUsage = 0x06; //键盘 rid.usUsagePage = 0x01; rid.usUsage = 0x02; 为鼠标
rid.dwFlags = RIDEV_INPUTSINK;
rid.hwndTarget = hwnd;
return RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE));
}
获取消息
在完成注册后,我们需要在窗口消息循环中添加处理函数;
一般Win32程序,在WndProc中添加:
case WM_INPUT:
{
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)); //先获取数据大小dwSize
LPBYTE lpb = new BYTE[dwSize]; //根据大小 创建
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize) //获取消息信息
break;
RAWINPUT *raw = (RAWINPUT*)lpb;
if (raw->header.dwType == RIM_TYPEKEYBOARD /*&& raw->data.keyboard.Flags == RI_KEY_MAKE*/) //注释掉的部分 用来判断 按键是否是按下
{
//这里添加 消息处理函数
int y = raw->data.keyboard.VKey; //按键 键值
int x = 1;
}
delete[] lpb;
DefWindowProc(hWnd, message, wParam, lParam);
}
完成。