Win32在控制台中实现后台获取键盘和鼠标原始输入的简单示例C/C++(标准读取方法,没有缓冲读取方法)

 

 

大体的流程

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 }

 

上一篇:CMU数据库(15-445) Lab4-CONCURRENCY CONTROL


下一篇:网络设备