错误 SetWindowsHookEx 和 GetRawInputData
Error SetWindowsHookEx and GetRawInputData
我有两个问题。
首先,我编写了一个小程序来捕获所有鼠标事件。我在一个单独的线程中启动它,但出现无法调试的错误:
#include <windows.h>
#include <iostream>
#include <thread>
HHOOK hookHandle;
LRESULT CALLBACK callBackHook(int nCode, WPARAM wParam, LPARAM lParam) {
if(nCode == HC_ACTION) {
std::cout << "Something!" << std::endl;
}
return CallNextHookEx(hookHandle, nCode,
wParam, lParam);
}
int mouseHook() {
hookHandle = SetWindowsHookEx(WH_MOUSE_LL , callBackHook, NULL, 0);
if(hookHandle == NULL) {
std::cout << "ERROR CREATING HOOK: ";
std::cout << GetLastError() << std::endl;
return 0;
}
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) != 0) {
std::cerr << "message!" << std::endl;
}
UnhookWindowsHookEx(hookHandle);
return 0;
}
int main(int argc, char *argv[])
{
std::thread mouse(mouseHook);
return 0;
}
错误消息(德语按钮显示 "Cancel"、"Retry"、"Ignore"):
其次,是否可以从callBackHook
函数的lParam
获取原始数据输入?我不知道如何在没有 HWND
.
的情况下注册输入设备
首先需要等待线程退出,使用mouse.join()
。如果直接主进程returns,它拥有的线程也会被终止,从而导致这个问题。
int main(int argc, char* argv[])
{
std::thread mouse(mouseHook);
mouse.join();
return 0;
}
其次,
I don't know how to register an input device without an HWND
别担心,您可以为此创建一个 Message-Only Window。
示例(删除一些错误检查):
#include <windows.h>
#include <iostream>
using namespace std;
LRESULT CALLBACK WindProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (Msg == WM_INPUT)
{
cout << "Something!" << endl;
HRAWINPUT hRawInput = (HRAWINPUT)lParam;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
int main()
{
WNDCLASSEX wcx = { 0 };
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.lpfnWndProc = WindProc;
wcx.hInstance = GetModuleHandle(NULL);
wcx.lpszClassName = TEXT("RawInputClass");
RegisterClassEx(&wcx);
HWND hWnd = CreateWindowEx(0, TEXT("RawInputClass"), NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
RAWINPUTDEVICE rid = { 0 };
rid.usUsagePage = 0x01;
rid.usUsage = 0x02; //mouse
rid.dwFlags = RIDEV_INPUTSINK;
rid.hwndTarget = hWnd;
RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE));
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
我有两个问题。
首先,我编写了一个小程序来捕获所有鼠标事件。我在一个单独的线程中启动它,但出现无法调试的错误:
#include <windows.h>
#include <iostream>
#include <thread>
HHOOK hookHandle;
LRESULT CALLBACK callBackHook(int nCode, WPARAM wParam, LPARAM lParam) {
if(nCode == HC_ACTION) {
std::cout << "Something!" << std::endl;
}
return CallNextHookEx(hookHandle, nCode,
wParam, lParam);
}
int mouseHook() {
hookHandle = SetWindowsHookEx(WH_MOUSE_LL , callBackHook, NULL, 0);
if(hookHandle == NULL) {
std::cout << "ERROR CREATING HOOK: ";
std::cout << GetLastError() << std::endl;
return 0;
}
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) != 0) {
std::cerr << "message!" << std::endl;
}
UnhookWindowsHookEx(hookHandle);
return 0;
}
int main(int argc, char *argv[])
{
std::thread mouse(mouseHook);
return 0;
}
错误消息(德语按钮显示 "Cancel"、"Retry"、"Ignore"):
其次,是否可以从callBackHook
函数的lParam
获取原始数据输入?我不知道如何在没有 HWND
.
首先需要等待线程退出,使用mouse.join()
。如果直接主进程returns,它拥有的线程也会被终止,从而导致这个问题。
int main(int argc, char* argv[])
{
std::thread mouse(mouseHook);
mouse.join();
return 0;
}
其次,
I don't know how to register an input device without an HWND
别担心,您可以为此创建一个 Message-Only Window。
示例(删除一些错误检查):
#include <windows.h>
#include <iostream>
using namespace std;
LRESULT CALLBACK WindProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (Msg == WM_INPUT)
{
cout << "Something!" << endl;
HRAWINPUT hRawInput = (HRAWINPUT)lParam;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
int main()
{
WNDCLASSEX wcx = { 0 };
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.lpfnWndProc = WindProc;
wcx.hInstance = GetModuleHandle(NULL);
wcx.lpszClassName = TEXT("RawInputClass");
RegisterClassEx(&wcx);
HWND hWnd = CreateWindowEx(0, TEXT("RawInputClass"), NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
RAWINPUTDEVICE rid = { 0 };
rid.usUsagePage = 0x01;
rid.usUsage = 0x02; //mouse
rid.dwFlags = RIDEV_INPUTSINK;
rid.hwndTarget = hWnd;
RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE));
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}