WINAPI的消息循环让我发疯
WINAPI's message loops drives me crazy
我一直在尝试使用 JNI 实现简单的低级键钩,一切都很顺利,直到我认为当 DLL 处于无限循环(消息循环)时我无法调用这些方法。 所以我决定创建新线程,但不知何故,在我使消息循环在自己的循环上运行之后,低级键钩停止响应,这意味着它不再调用 keyproc, 我不知道这是为什么?还有其他解决方法吗?我需要能够在键盘挂钩仍在工作时调用 DLL 的方法。
我当前的代码就像
注册键盘挂钩:
keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboardProc, hInstance, 0);
启动线程
HANDLE threadHandle = CreateThread(NULL, 0, ThreadProc, NULL, 0, &threadId);
我的键盘程序和线程程序如下:
DWORD WINAPI ThreadProc(LPVOID lpVoid) {
MSG msg;
while(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK keyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
KBDLLHOOKSTRUCT keyEvent = *((KBDLLHOOKSTRUCT*)lParam);
jint vkCode = keyEvent.vkCode;
jint flags = keyEvent.flags;
jint action = wParam;
(*globalEnv).CallVoidMethod(globalObj, keyboardMethodId, vkCode, flags, action);
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
我哪里出错了?我确定它不是 java,因为即使我为它从未调用的键程序添加简单的日志记录。但是,如果我停止使用线程并在主线程上运行消息循环,它可以正常工作,但 DLL 不会响应它之后的方法调用。
您需要在
名为 SetWindowsHookEx() 的同一线程上泵送消息循环。 因此,只需将调用移动到您的 ThreadProc() 中即可。 当然,请注意您的 CallVoidMethod() 回调也在同一线程上运行,因此请注意您在该函数中执行的操作。 您访问的任何共享状态都需要使用锁进行保护。
您正在尝试安装桌面范围的挂钩,该挂钩跨越桌面的所有进程。也就是说,DLL 映射到具有特定于进程的全局变量集的多个进程中。您在其他进程中没有有效的globalEnv
,并且可能会遇到访问冲突或类似错误(可以使用共享数据细分受众群创建全局变量,有关详细信息,请参阅此文章)。
要安装特定于线程的钩子,您将需要不同类型的钩子(WH_KEYBOARD_LL
仅是全局的!)和 SetWindowsHookEx
中的非零最后一个参数。
相关文章:
- 如何循环打印顶点结构
- 如何在C++中从两个单独的for循环中添加两个数组
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 正在尝试了解输入验证循环
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 循环后如何继续阅读
- Ardunio UNO解决了多个重叠的定时器循环
- Eigen如何在容器循环中干净地附加矩阵
- 在某些循环内使用vector.push_back时出现分段错误
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- 为什么我的for循环不能正确获取argv
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- while循环中while循环的时间复杂度是多少
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 为什么在这个代码结束循环中没有得到结束
- 在基于范围的for循环中使用结构化绑定声明
- 用于C++中带有数组和指针的循环
- 循环中的随机函数
- 是什么阻止DOMTimerCoordinator::NextID进入无休止的循环
- WINAPI的消息循环让我发疯