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.
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
. I have verified this with those printf's and gdb. Why does GetMessage
not return? 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.