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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM