【发布时间】:2020-02-07 02:17:02
【问题描述】:
我有两个问题。
首先,我编写了一个小程序来捕获所有鼠标事件。我在一个单独的线程中启动它,我得到一个我无法调试的错误:
#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;
}
错误消息(德语按钮说“取消”、“重试”、“忽略”):
其次,是否可以从callBackHook函数的lParam获取原始数据输入?我不知道如何注册没有HWND 的输入设备。
【问题讨论】:
-
如果去掉
cout/cerr语句,是否还会出现错误?尝试改用OutputDebugString()。至于lParam,WH_MOUSE_LL回调在lParam中接收MSLLHOOKSTRUCT*指针,因此您可以访问的唯一数据是MSLLHOOKSTRUCT结构提供的数据。原始输入 API 需要HWND来传递WM_INPUT消息,这是您访问原始输入数据的唯一方式。 -
你需要等待线程结束(使用
mouse.join())。主进程创建线程后会直接返回0,导致线程报此错误。 -
我不知道如何注册没有HWND的输入设备,你可以创建一个Message-Only Window
-
对话框上有说明。它说:“按重试调试应用程序”。这将带您直接进入调试器中的错误操作。确保您了解
std::thread与destruction 相关的规则。如果您不想参与其中,请改用std::jthread。这需要一个支持 C++20 的 C++ 编译器。
标签: c++ winapi event-handling runtime-error