0

以下代码工作正常。当用户按下一个键时,它会发出消息。但有些事情我不知道。消息循环在这里的作用是什么?我读到调用会在窗口中SetWindowsHookEx(...)注册一个函数,当注册类型的事件发生时,窗口会自动调用相应的函数。毫无疑问,如果不给消息循环它的空间,我看不到输出。

#include<iostream>
#include <windows.h>
using namespace std;

HINSTANCE hinst = NULL;
static HHOOK handleKeyboardHook = NULL;
static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);

void setWinHook() {
  handleKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc,NULL, 0);
if(handleKeyboardHook == NULL) {
    cout << "is NULL";
} else {
    cout << "is not NULL";
}
  cout<<("Inside function setWinHook !");
}

static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
 cout << ("You pressed a key !\n");
  return CallNextHookEx(handleKeyboardHook, nCode, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
 handleKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInstance, 0);
 MSG msg;
 while(GetMessage(&msg, NULL, 0, 0))
 {
   TranslateMessage(&msg);
   DispatchMessage(&msg);
 }
 return msg.wParam;
}

编辑

退出程序(关闭控制台窗口)是否取消注册钩子?

编辑 2

Dispatch Message在这里起什么作用?根据文档,它会向窗口过程发送一条消息,但即使我排除了它,它也不会影响输出。

4

3 回答 3

2

Windows 中的所有事件,甚至是您的示例中使用的低级键盘事件,都是使用普通消息事件发送的。因此,为了让程序能够感知键盘事件,它必须使用事件循环来处理消息。

于 2012-05-29T08:20:59.360 回答
2

如果没有循环,程序将立即退出,并且钩子也会立即被移除。你不能注册一个钩子并退出——如果有缺陷的程序在它们之后留下太多被遗忘的钩子,系统就会变得一团糟。一旦你的进程终止,钩子就会被安排删除。

我不记得低级键盘钩子了,但是许多其他钩子的回调只在GetMessage/内部调用PeekMessage,而不是在其他线程上调用,所以仅仅一个无限循环是不够的——它必须是一个消息循环。

于 2012-05-29T08:22:17.073 回答
0

“Dispatch Message 在这里扮演什么角色?根据文档,它向窗口过程发送消息,但在这里即使我排除它,它也不会影响输出。”

DispatchMessage 非常没用,因为控制台窗口没有收到太多消息。只有当窗口失去焦点时才会收到消息。

于 2012-07-21T11:52:03.480 回答