【问题标题】:Win32 -- how to manage my mouse hook threadWin32——如何管理我的鼠标钩子线程
【发布时间】:2011-03-14 09:09:53
【问题描述】:

我已经成功地让我的低级鼠标挂钩代码工作,但我观察到的一些行为我不太理解。如果我生成一个安装鼠标钩的线程,一切正常。当我不再需要它运行时,我让线程在退出程序时自动销毁,我想我可以轻松地显式终止线程。然而,这让我感到不安,因为我最终不会调用UnhookWindowsHookEx 来释放鼠标挂钩资源。

所以我试图颠倒我的测试程序中的逻辑。我尝试生成一个休眠一段时间的线程,然后写入全局变量。然后我从主线程调用钩子安装例程。这里是一个循环,它检查全局变量并在适当的时候退出循环。然后它将能够自行清理。以下是相关代码:

static int willQuit = 0;
unsigned WINAPI MouseProcessingProc (void *param) {
 try { // will catch exceptions and not propagate them
  HHOOK mousehook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc,
    NULL, 0);
  if (mousehook == NULL) printf("Mousehook error %u\n",GetLastError());

  while(true) {
   MSG msg;
   if (GetMessage(&msg,0,0,0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
   }
   if (willQuit) { printf("willQuit no longer 0!\n"); break; }
   printf("Looped\n");
  }
  willQuit = 0;
  UnhookWindowsHookEx(mousehook);

  printf("Procedure completed without exceptional events.\n");
 } catch (const std::string& s) {
  printf("String exception: %s\n", s.c_str());
 } catch (int i) {
  printf("Int exception: %d\n", i);
 } catch (...) {
  printf("Unknown default exception!\n");
 }
 printf("Exiting thread execution.\n");
 return 0;
}

void spawn() {
 printf("Spawning Mouse thread\n");
 _beginthreadex(NULL,0,MouseProcessingThreadProc,NULL,0,0);
}

void run() {
 printf("Running Mouse routine\n");
 MouseProcessingThreadProc(0);
}

void stop() {
 printf("Stopping Mouse routine\n");
 willQuit = 1;
}

unsigned WINAPI threadproc(void *param) {
    Sleep(500);
    printf("Spawned thread says 3");
    Sleep(500);
    printf("2");
    Sleep(500);
    printf("1\n");
    Sleep(500);
    printf("Spawned thread calls stop now -->\n");
    stop();
}

int main() {
    _beginthreadex(NULL,0,threadproc,NULL,0,0); // waiter and stopper thread
    run(); // become the mousehook thread
    printf("Completed\n");
    return 0;
}

现在发生的情况是,我拥有的小消息轮询循环(while 循环)从未真正从GetMessage 调用返回,因此它永远无法到达它检查willQuit 的地步。我已经用那些 printf 和 gdb 验证了这一点。为什么GetMessage 不返回?有没有更好的方法来设置我的鼠标钩线?还是我在尝试做一些我不应该做的事情?

感谢阅读。

【问题讨论】:

    标签: c++ c multithreading winapi hook


    【解决方案1】:

    在您的 stop() 例程中,设置 willQuit 变量后,您还需要 POST 任何消息到运行 MouseProcessingProc 的线程,因此 GetMessage 将返回。请参阅PostThreadMessage API。

    编辑:您还可以使用事件或其他同步对象,而不是使用 Windows 消息和消息泵。因此,消息泵将被 WaitForSingleObject 之类的东西取代,这是您可以发出信号的一些内核对象,例如事件。

    【讨论】:

    • 这很有意义。现在,只创建我自己的自定义线程消息似乎更合适,当鼠标处理线程收到退出消息时,它们可以自行退出。一个非常自然的解决方案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-31
    • 1970-01-01
    • 1970-01-01
    • 2011-01-04
    • 2010-12-04
    • 2019-12-28
    相关资源
    最近更新 更多