我试图了解如何初始化LowLevelKeyboardProc钩子。
在下面所示的键盘记录器的最小方法中,为什么我需要消息循环来使钩子工作,即使它只是在第一个循环中挂起并且从不打印"msg\r"?
如果没有机会重新检查同时状态,我怎么能解开钩子?
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
LRESULT CALLBACK LLKBProc(int nCode, WPARAM wParam, LPARAM lParam) {
KBDLLHOOKSTRUCT *keyMetaP = (KBDLLHOOKSTRUCT *) lParam;
printf("nkey = %x", keyMetaP->vkCode);
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
int main() {
// get handle to process
HINSTANCE hExe = GetModuleHandle(NULL);
// set hook
HHOOK keyHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC) LLKBProc, hExe, 0);
// msg loop
MSG msg;
while ( GetMessage(&msg, 0, 0, 0) != -1 ) {
TranslateMessage(&msg);
DispatchMessage(&msg);
printf("MSGrn");
}
UnhookWindowsHookEx(keyHook);
return 1;
}
消息循环存在,因此程序不会简单地死亡。现在它没有任何终止条件,但是在主线程中没有某种循环,程序将简单地进行UnhookWindowsHookEx调用,然后终止。
来自 MSDN (WH_KEYBOARD_LL(:
此挂钩在安装它的线程的上下文中调用。通过向安装挂钩的线程发送消息来进行调用。因此,安装挂钩的线程必须具有消息循环。
若要中止来自不同线程的消息循环,可以使用PostThreadMessage
发布WM_NULL或WM_QUIT,或者如果要使用事件作为停止信号,可以使用MsgWaitForMultipleObjects
而不是GetMessage
。
从钩子内部中止,你可能只使用 PostQuitMessage
。