为什么必须将SetWindowsHookEx与Windows消息队列一起使用

Ha1*_*wed 15 c++ hook message-queue

我一直在尝试使用钩子的东西,我不明白为什么钩子必须与消息队列一起使用

hook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, 0);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
        TranslateMessage(&msg);
        DispatchMessage(&msg);
}
UnhookWindowsHookEx(hook);
Run Code Online (Sandbox Code Playgroud)

为什么这样的东西不起作用?

hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, NULL, 0);
cin >> aKey;
UnhookWindowsHookEx(hook);
Run Code Online (Sandbox Code Playgroud)

使用增强螺纹和屏障也不起作用.为什么不能以另一种方式完成钩子和钩子之间的等待?

编辑:

我在创建这个示例时犯了一个错误,我创建了一个WH_KEYBOARD_LL挂钩,而不是WH_KEYBOARD,(我认为它不会产生很大的影响)

循环永远不会只在GetMessage函数上等待.

循环仅在我发布退出消息时执行,PostThreadMessage(id, WM_QUIT, 2323, NULL);所以我不明白它在等待时做了什么,是否有一些内部处理?

有关:

C++ SetWindowsHookEx WH_KEYBOARD_LL正确设置

如何在Win32控制台窗口上设置CBT挂钩?

Han*_*ant 33

低级别挂钩WH_KEYBOARD_LL和WH_MOUSE_LL与所有其他挂钩不同.它们不需要将DLL注入目标进程.相反,Windows会在您自己的进程中直接调用您的钩子回调.要使这项工作,需要一个消息循环.Windows没有其他机制在主线程上进行回调,只有当您调用Get/PeekMessage()以便Windows处于控制状态时才能进行回调.

像WH_KEYBOARD这样的全局钩子是非常不同的.它需要一个DLL,并且回调发生在处理键盘消息的进程中.您需要某种进程间通信才能让自己的程序意识到这一点.命名管道是通常的选择.否则当然要求该注入过程泵送消息循环.否则它不会得到键盘消息.

喜欢低级钩子,它们容易上手.但泵或它不会工作.并且要注意超时,如果你没有足够的响应,那么Windows会在没有通知的情况下杀死你的钩子.

了解低级鼠标和键盘钩子(win32)

  • 你理解正确.没有其他方法可以安全地将调用注入线程,它必须是空闲的.这就是消息循环存在的原因. (2认同)