The Difference between to usages of SetWindowsHookEx
首先:我在Windows XP-32位上使用Visual Studio 2010。
现在,我正在尝试编写一个DLL,它将使另一个应用程序能够与低级键盘挂钩一起使用。
即使我可以使用它-现在我想了解原因。
非工作代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #include <Windows.h> #include <stdio.h> static HINSTANCE hinst; static HHOOK kbdHook = NULL; LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { printf(":"); fflush(stdout); return CallNextHookEx(NULL, nCode, wParam, lParam); } DWORD WINAPI ThreadProc(LPVOID lpParameter) { MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: hinst = hinstDLL; CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); kbdHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hinst, 0); break; case DLL_PROCESS_DETACH: UnhookWindowsHookEx(kbdHook); break; default: break; } return TRUE; } |
工作代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #include <Windows.h> #include <stdio.h> static HINSTANCE hinst; static HHOOK kbdHook = NULL; LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { printf(":"); fflush(stdout); return CallNextHookEx(NULL, nCode, wParam, lParam); } DWORD WINAPI ThreadProc(LPVOID lpParameter) { MSG msg; kbdHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: hinst = hinstDLL; CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); break; case DLL_PROCESS_DETACH: UnhookWindowsHookEx(kbdHook); break; default: break; } return TRUE; } |
唯一的区别是我将
问题:为什么这一切都不同?
LowLevelKeyboardProc回调函数的文档中对此进行了全部解释:
This hook is called in the context of the thread that installed it. The call is made by sending a message to the thread that installed the hook. Therefore, the thread that installed the hook must have a message loop.
您的非工作代码将钩子安装在线程上,该线程不会运行消息循环。