C++ 为什么必须将 SetWindowsHookEx 与 Windows 消息队列一起使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7458807/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why must SetWindowsHookEx be used with a windows message queue
提问by Ha11owed
I've been trying some things with hooks, and I don't understand why hooks must be used with a 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);
Why doesn't something like this work ?
为什么这样的事情不起作用?
hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, NULL, 0);
cin >> aKey;
UnhookWindowsHookEx(hook);
Using boost threads, and a barrier doesn't work either. Why can't the waiting between the hook and unhook be done in another manner ?
使用 boost 线程,屏障也不起作用。为什么不能以另一种方式完成钩子和脱钩之间的等待?
EDIT:
编辑:
I did a mistake when I created this sample, I create a WH_KEYBOARD_LL hook, not WH_KEYBOARD, (I don't think it makes a big difference)
我在创建这个示例时犯了一个错误,我创建了一个 WH_KEYBOARD_LL 钩子,而不是 WH_KEYBOARD,(我不认为它有很大的不同)
Also the loop never executes only waits on the GetMessage function.
此外,循环从不执行,只等待 GetMessage 函数。
The loop executes only when I post the quit message PostThreadMessage(id, WM_QUIT, 2323, NULL);
so I don't understand what does it do beside waiting, is there some internal processing ?
循环仅在我发布退出消息时执行,PostThreadMessage(id, WM_QUIT, 2323, NULL);
所以我不明白它除了等待之外还做什么,是否有一些内部处理?
RELATED:
有关的:
C++ SetWindowsHookEx WH_KEYBOARD_LL Correct Setup
C++ SetWindowsHookEx WH_KEYBOARD_LL 正确设置
回答by Hans Passant
The low-level hooks, WH_KEYBOARD_LL and WH_MOUSE_LL are different from all the other hooks. They don't require a DLL to be injected into the target process. Instead, Windows calls your hook callback directly, inside your own process. To make that work, a message loop is required. There is no other mechanism for Windows to make callbacks on your main thread, the callback can only occur when you've called Get/PeekMessage() so that Windows is in control.
低级钩子 WH_KEYBOARD_LL 和 WH_MOUSE_LL 与所有其他钩子不同。它们不需要将 DLL 注入目标进程。相反,Windows 在您自己的进程中直接调用您的钩子回调。为了使其工作,需要一个消息循环。Windows 没有其他机制可以在您的主线程上进行回调,只有在您调用 Get/PeekMessage() 以便 Windows 处于控制之下时才会发生回调。
A global hook like WH_KEYBOARD is very different. It requires a DLL and the callback occurs within the process that processes the keyboard message. You need some kind of inter-process communication to let your own program be aware of this. Named pipes are the usual choice. Which otherwise of course requires that this injected process pumps a message loop. It wouldn't get keyboard messages otherwise.
像 WH_KEYBOARD 这样的全局钩子非常不同。它需要一个 DLL,并且回调发生在处理键盘消息的进程中。您需要某种进程间通信来让您自己的程序意识到这一点。命名管道是通常的选择。否则当然需要这个注入的进程泵出一个消息循环。否则它不会收到键盘消息。
Favor a low-level hook, they are mucheasier to get going. But do pump or it won't work. And beware of timeouts, if you're not responsive enough then Windows will kill your hook without notice.
喜欢低级别的钩子,它们更容易上手。但是做泵或它不会工作。并注意超时,如果您的响应不够灵敏,那么 Windows 将在没有通知的情况下终止您的钩子。
回答by shf301
Windows Hooks hook the Windows message loop: http://msdn.microsoft.com/en-us/library/ms644959#wh_keyboardhook
Windows Hooks 钩住 Windows 消息循环:http: //msdn.microsoft.com/en-us/library/ms644959#wh_keyboardhook
The WH_KEYBOARD hook enables an application to monitor message traffic for WM_KEYDOWN and WM_KEYUP messages about to be returned by the GetMessage or PeekMessage function. You can use the WH_KEYBOARD hook to monitor keyboard input posted to a message queue.
WH_KEYBOARD 挂钩使应用程序能够监视将由 GetMessage 或 PeekMessage 函数返回的 WM_KEYDOWN 和 WM_KEYUP 消息的消息流量。您可以使用 WH_KEYBOARD 挂钩来监视发布到消息队列的键盘输入。
Console applications don't pump messages themselves - the console process does. So it won't work unless the process has a message loop.
控制台应用程序本身不会抽取消息——控制台进程会。所以除非进程有消息循环,否则它不会工作。
See:
看:
How can I set up a CBT hook on a Win32 console window?