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

时间:2011-09-18 00:45:01

标签: 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);

为什么这样的事情不起作用?

hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, NULL, 0);
cin >> aKey;
UnhookWindowsHookEx(hook);

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

编辑:

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

此外,循环永远不会仅执行等待GetMessage函数。

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

相关:

C++ SetWindowsHookEx WH_KEYBOARD_LL Correct Setup

How can I set up a CBT hook on a Win32 console window?

2 个答案:

答案 0 :(得分:33)

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

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

赞成一个低级别的钩子,他们很多更容易开始。但泵或它不会工作。并且要注意超时,如果你没有足够的响应,那么Windows会在没有通知的情况下杀死你的钩子。

Understanding the low-level mouse and keyboard hook (win32)

答案 1 :(得分:4)

Windows Hooks挂钩Windows消息循环:http://msdn.microsoft.com/en-us/library/ms644959#wh_keyboardhook

  

WH_KEYBOARD挂钩使应用程序能够监控消息流量   对于要返回的WM_KEYDOWN和WM_KEYUP消息   GetMessage或PeekMessage函数。您可以使用WH_KEYBOARD钩子   监视发布到消息队列的键盘输入。

控制台应用程序本身不会提取消息 - 控制台进程会这样做。所以除非进程有消息循环,否则它将无法工作。

请参阅:

How can I set up a CBT hook on a Win32 console window?

C++ SetWindowsHookEx WH_KEYBOARD_LL Correct Setup