大体的流程
1.必须创建一个窗口句柄,后台获取原始输入所必须的
2.注册原始输入
3.从消息循环中获取WM_INPUT消息
4.读取
最后有整个示例
简单创建窗口句柄的方法
1 class CreateWindowHandle { 2 3 static void _CreateWindowClass(HINSTANCE moduleHandle, LPCWSTR windowsClassName) { 4 WNDCLASSEXW wcex; 5 6 wcex.cbSize = sizeof(WNDCLASSEX); 7 8 wcex.style = CS_HREDRAW | CS_VREDRAW; 9 wcex.lpfnWndProc = DefWindowProcW; 10 wcex.cbClsExtra = 0; 11 wcex.cbWndExtra = 0; 12 wcex.hInstance = moduleHandle; 13 wcex.hIcon = nullptr; 14 wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); 15 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 16 wcex.lpszMenuName = nullptr; 17 wcex.lpszClassName = windowsClassName; 18 wcex.hIconSm = nullptr; 19 20 RegisterClassExW(&wcex); 21 } 22 23 static HWND _CreateWindow(HINSTANCE moduleHandle, LPCWSTR windowsClassName) { 24 25 auto windowsHandle = CreateWindowExW(0L, windowsClassName, L"Window", WS_OVERLAPPEDWINDOW, 26 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, moduleHandle, nullptr); 27 28 return windowsHandle; 29 } 30 31 public: 32 static HWND Create() { 33 auto moduleHandle = static_cast<HINSTANCE>(GetModuleHandleW(nullptr)); 34 35 WCHAR windowsClassName[] = L"fsdfsrewrwegfdgfd"; 36 37 CreateWindowHandle::_CreateWindowClass(moduleHandle, windowsClassName); 38 39 return CreateWindowHandle::_CreateWindow(moduleHandle, windowsClassName); 40 } 41 };
可以这样使用
HWND windowHandle = CreateWindowHandle::Create();
注册鼠标与键盘的方法
1 void RegisterMouseRawInput(HWND handle) { 2 3 RAWINPUTDEVICE rid; 4 5 rid.usUsagePage = 0x01; 6 rid.usUsage = 0x02; 7 rid.dwFlags = RIDEV_INPUTSINK; 8 rid.hwndTarget = handle; 9 10 RegisterRawInputDevices(&rid, 1, sizeof(rid)); 11 } 12 13 void RegisterKeyboardRawInput(HWND handle) { 14 15 RAWINPUTDEVICE rid; 16 17 rid.usUsagePage = 0x01; 18 rid.usUsage = 0x06; 19 rid.dwFlags = RIDEV_INPUTSINK; 20 rid.hwndTarget = handle; 21 22 RegisterRawInputDevices(&rid, 1, sizeof(rid)); 23 }
读取原始输入的方法
1 void UsedRawInput(LPARAM lParam) { 2 char buffer[1024]; 3 4 UINT dwSize = 1024; 5 //其实GetRawInputData可以分两步调用,第一次获取输出结构的大小,分配空间后调用第二次,但如果知道大小的话就可以省略第一次,所以我只调用了一次 6 GetRawInputData(reinterpret_cast<HRAWINPUT>(lParam), RID_INPUT, buffer, &dwSize, sizeof(RAWINPUTHEADER)); 7 8 auto raw = reinterpret_cast<RAWINPUT*>(buffer); 9 10 if (raw->header.dwType == RIM_TYPEKEYBOARD) 11 { 12 std::cout << "raw key board input" << std::endl; 13 } 14 else if (raw->header.dwType == RIM_TYPEMOUSE) 15 { 16 std::cout << "raw mouse input" << std::endl; 17 } 18 else { 19 20 } 21 }
从事件循环中获取输入的方法
1 int main() { 2 HWND windowHandle = CreateWindowHandle::Create(); 3 4 RegisterKeyboardRawInput(windowHandle); 5 6 RegisterMouseRawInput(windowHandle); 7 8 9 10 MSG msg; 11 12 while (GetMessage(&msg, nullptr, 0, 0)) 13 { 14 if (msg.message == WM_INPUT) { 15 16 UsedRawInput(msg.lParam); 17 //如果是在前台获取的原始输入则必须调用DispatchMessage(&msg);来清理 18 if (GET_RAWINPUT_CODE_WPARAM(msg.wParam) == RIM_INPUT) { 19 DispatchMessage(&msg); 20 } 21 else { 22 23 } 24 25 } 26 else { 27 DispatchMessage(&msg); 28 } 29 } 30 31 return (int)msg.wParam; 32 }
整个示例
1 #include <iostream> 2 #include <windows.h> 3 4 5 6 class CreateWindowHandle { 7 8 static void _CreateWindowClass(HINSTANCE moduleHandle, LPCWSTR windowsClassName) { 9 WNDCLASSEXW wcex; 10 11 wcex.cbSize = sizeof(WNDCLASSEX); 12 13 wcex.style = CS_HREDRAW | CS_VREDRAW; 14 wcex.lpfnWndProc = DefWindowProcW; 15 wcex.cbClsExtra = 0; 16 wcex.cbWndExtra = 0; 17 wcex.hInstance = moduleHandle; 18 wcex.hIcon = nullptr; 19 wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); 20 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 21 wcex.lpszMenuName = nullptr; 22 wcex.lpszClassName = windowsClassName; 23 wcex.hIconSm = nullptr; 24 25 RegisterClassExW(&wcex); 26 } 27 28 static HWND _CreateWindow(HINSTANCE moduleHandle, LPCWSTR windowsClassName) { 29 30 auto windowsHandle = CreateWindowExW(0L, windowsClassName, L"Window", WS_OVERLAPPEDWINDOW, 31 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, moduleHandle, nullptr); 32 33 return windowsHandle; 34 } 35 36 public: 37 static HWND Create() { 38 auto moduleHandle = static_cast<HINSTANCE>(GetModuleHandleW(nullptr)); 39 40 WCHAR windowsClassName[] = L"fsdfsrewrwegfdgfd"; 41 42 CreateWindowHandle::_CreateWindowClass(moduleHandle, windowsClassName); 43 44 return CreateWindowHandle::_CreateWindow(moduleHandle, windowsClassName); 45 } 46 }; 47 48 49 50 void RegisterMouseRawInput(HWND handle) { 51 52 RAWINPUTDEVICE rid; 53 54 rid.usUsagePage = 0x01; 55 rid.usUsage = 0x02; 56 rid.dwFlags = RIDEV_INPUTSINK; 57 rid.hwndTarget = handle; 58 59 RegisterRawInputDevices(&rid, 1, sizeof(rid)); 60 } 61 62 void RegisterKeyboardRawInput(HWND handle) { 63 64 RAWINPUTDEVICE rid; 65 66 rid.usUsagePage = 0x01; 67 rid.usUsage = 0x06; 68 rid.dwFlags = RIDEV_INPUTSINK; 69 rid.hwndTarget = handle; 70 71 RegisterRawInputDevices(&rid, 1, sizeof(rid)); 72 } 73 74 void UsedRawInput(LPARAM lParam) { 75 char buffer[1024]; 76 77 UINT dwSize = 1024; 78 //其实GetRawInputData可以分两步调用,第一次获取输出结构的大小,分配空间后调用第二次,但如果知道大小的话就可以省略第一次,所以我只调用了一次 79 GetRawInputData(reinterpret_cast<HRAWINPUT>(lParam), RID_INPUT, buffer, &dwSize, sizeof(RAWINPUTHEADER)); 80 81 auto raw = reinterpret_cast<RAWINPUT*>(buffer); 82 83 if (raw->header.dwType == RIM_TYPEKEYBOARD) 84 { 85 std::cout << "raw key board input" << std::endl; 86 } 87 else if (raw->header.dwType == RIM_TYPEMOUSE) 88 { 89 std::cout << "raw mouse input" << std::endl; 90 } 91 else { 92 93 } 94 } 95 96 int main() { 97 HWND windowHandle = CreateWindowHandle::Create(); 98 99 RegisterKeyboardRawInput(windowHandle); 100 101 RegisterMouseRawInput(windowHandle); 102 103 104 105 MSG msg; 106 107 while (GetMessage(&msg, nullptr, 0, 0)) 108 { 109 if (msg.message == WM_INPUT) { 110 111 UsedRawInput(msg.lParam); 112 //如果是在前台获取的原始输入则必须调用DispatchMessage(&msg);来清理 113 if (GET_RAWINPUT_CODE_WPARAM(msg.wParam) == RIM_INPUT) { 114 DispatchMessage(&msg); 115 } 116 else { 117 118 } 119 120 } 121 else { 122 DispatchMessage(&msg); 123 } 124 } 125 126 return (int)msg.wParam; 127 }