我正在尝试捕获全局鼠标和键盘输入。
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode >= 0) {
if (wParam == WM_RBUTTONDOWN) printf("right mouse down\n");
if (wParam == WM_RBUTTONUP) printf("right mouse up\n");
}
return CallNextHookEx(0, nCode, wParam, lParam);
}
HHOOK mousehook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, NULL, 0);
while(true) {
MSG msg;
if (PeekMessage(&msg,0,0,0,PM_REMOVE)) {
printf("msg recvd\n");
TranslateMessage(&msg);
DispatchMessage(&msg);
}
#ifdef TEST
Sleep(50);
#endif
}
如果我在代码中用#define TEST
来加入Sleep
,那么鼠标会变得非常迟缓,这是可以预料到的,因为这样只允许鼠标每秒更新20次。而如果没有Sleep
,那么CPU将被占用100%。但现在还好(如果使用GetMessage
,这种情况就不会出现)。
据我所知,低级钩子通过切换到安装它的进程,并发送某种消息给该进程以执行钩子回调来工作。但有一点让我困惑,为什么我的程序永远不会打印“msg recvd”,但在单击右键时会打印“right mouse down / up”。这使我得出结论,我的MouseHookProc
在PeekMessage
调用期间被调用。它只是一些特殊消息,并且PeekMessage
返回0。但我仍然需要调用PeekMessage
或其等效物。
由于我的程序需要执行很多任务,我显然不能通过调用需要50毫秒才能返回的另一个函数来降低消息泵送循环(即调用PeekMessage
)的效率。如何将我的程序多线程化以在同时进行繁重任务时保持鼠标的响应性?在多线程win32程序中,仍然只有一个消息队列,对吗?
更新:阅读了MS的文档后,我想我知道该怎么做了。我只需在我的应用程序中生成一个线程来调用SetWindowsHookEx
以注册鼠标钩子,然后坐在自己的消息循环中,系统将负责将鼠标更新发送到此线程。它将可以在MouseHookProc
中自由地执行任何操作,而我的应用程序的其余部分将独立运行。
MouseHookProc
,并且在EXE中有SetWindowsHookEx
和PeekMessage
循环? - Oleg