简体   繁体   English

Win32 —如何管理鼠标钩子线程

[英]Win32 — how to manage my mouse hook thread

I have successfully gotten my low-level mouse hook code to work, but there are some behaviors I'm observing that I don't quite understand. 我已经成功获取了低级鼠标挂钩代码,但我观察到的某些行为我不太了解。 Everything works fine if I spawn a thread which installs the mouse hook. 如果我生成一个安装鼠标钩子的线程,则一切正常。 When i no longer need it running, I let the thread get destroyed automatically as I exit the program, and I imagine I can easily terminate the thread explicitly. 当我不再需要运行该线程时,我让线程在退出程序时自动销毁,并且我可以轻松地显式终止该线程。 However this makes me uneasy because I won't end up calling UnhookWindowsHookEx to free the mouse hook resources. 但这使我感到不安,因为我最终不会调用UnhookWindowsHookEx释放鼠标钩子资源。

So I tried to reverse the logic in my testing program. 因此,我试图颠倒测试程序中的逻辑。 I try spawning a thread which sleeps for a bit, and then writes to a global variable. 我尝试生成一个休眠了一段时间的线程,然后将其写入全局变量。 Then I call the hook installing routine from the primary thread. 然后我从主线程调用钩子安装例程。 In here is a loop which checks the global variable and exits the loop when appropriate. 这里是一个检查全局变量并在适当时退出循环的循环。 Then it will be able to clean up after itself. 然后它将能够自行清理。 Here is the relevant code: 以下是相关代码:

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;
}

Now what's happening is that the little message polling loop I have (the while loop) never really returns from the GetMessage call, so it can never reach the point where it checks willQuit . 现在发生的事情是,我拥有的小消息轮询循环( while循环)从未真正从GetMessage调用返回,因此它永远无法到达检查willQuit I have verified this with those printf's and gdb. 我已经用那些printf和gdb验证了这一点。 Why does GetMessage not return? 为什么GetMessage不返回? Is there a better way to set up my mouse hook thread? 有没有更好的方法来设置我的鼠标挂钩线程? Or am I trying to do something that I am not supposed to do? 还是我正在尝试做我不应该做的事情?

thanks for reading. 谢谢阅读。

In your stop() routine, after setting the willQuit variable, you will also need to POST any message to the thread running MouseProcessingProc, so GetMessage will return. 在您的stop()例程中,设置willQuit变量后,您还需要将任何消息发布到运行MouseProcessingProc的线程,因此GetMessage将返回。 See PostThreadMessage API. 请参阅PostThreadMessage API。

EDIT: You could also use an event, or other sync object, instead of using windows messages and the message pump. 编辑:您还可以使用事件或其他同步对象,而不是使用Windows消息和消息泵。 So the message pump would get replace by something like WaitForSingleObject, some kernel object that you can signal, such as an event. 因此,消息泵将被WaitForSingleObject之类的东西替换,WaitForSingleObject是您可以发信号通知的某些内核对象,例如事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM