c++ - 了解低级鼠标和键盘钩子(Hook)(win32)

标签 c++ multithreading winapi

我正在 try catch 全局鼠标和键盘输入。

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,它就会消失)。

现在据我了解,低级 Hook 通过上下文切换到安装它的进程来工作,然后向进程发送某种消息以使其执行 Hook 回调。不过,让我有点困惑的是,为什么我的程序永远不会打印“msg recvd”,但每当我单击鼠标右键时它会打印“鼠标右键向下/向上”。这使我得出结论,在 PeekMessage 调用期间正在调用我的 MouseHookProc。它恰好是某种特殊消息,PeekMessage 返回 0。但我仍然需要调用 PeekMessage 或类似的方法。

由于我的程序需要做很多事情,我显然不能通过调用另一个需要 50 毫秒才能返回的函数来减轻我的消息泵循环(调用 PeekMessage 的那个) .我如何对我的程序进行多线程处理以保持鼠标响应能力,同时做一些繁重的工作?在多线程的win32程序中,还是只有一个消息队列吧?

更新:在阅读了 MS 的文档后,我想我知道我应该做什么。我应该在我的应用程序中生成一个线程,调用 SetWindowsHookEx 来注册鼠标钩子(Hook),然后坐在它自己的消息循环中,系统将负责将鼠标更新发送到该线程。它可以自由地在 MouseHookProc 中做任何想做的事情,而我的应用程序的其余部分将独立运行。

最佳答案

问题在于您的消息循环,因为您使用 PeekMessage(),它会消耗 100% 的 CPU 周期。即使您不轮询消息,Windows 也知道如何使钩子(Hook)保持事件状态,请使用 GetMessage() 来解决您的问题。使用 Sleep(1) 也可以解决您的问题,但这里没有必要。

Why must SetWindowsHookEx be used with a windows message queue

关于c++ - 了解低级鼠标和键盘钩子(Hook)(win32),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3134183/

相关文章:

Python在线程定时器中运行SQL语句

java - 在 JavaFX 中运行线程

c++ - 为什么不能将不完整的类型转换为 void?

java - 具有不断变化的键值的优先级队列

c# - 单线程

winapi - 找到notepad.exe和mspaint.exe的路径

c++ - 从控制台应用程序动态使用 DLL

windows - (Windows)系统文件缓存磁盘回写失败会出现什么错误?他们是如何被报道的?

c++ - 如何将数据从一个结构链接到另一个结构

c++ - 从构造函数调用 shared_from_this