windows - 究竟为什么是 TranslateMessage

标签 windows winapi visual-c++

我正在尝试理解“消息循环”。 这是它的样子:

MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

到目前为止,我很清楚(至少我希望如此)这个概念。当用户使用键盘和鼠标与 Windows 应用程序交互时,这些事件被相应的设备驱动程序转换为适当的消息并发布到系统消息队列。

操作系统从队列中一条一条地移除消息,并检查每条消息以将它们发送到负责创建目标窗口的相应应用程序线程的队列。

现在在我的申请中

MSG msg;
GetMessage(&msg, NULL, 0, 0);

从线程特定消息队列中删除消息并填充 MSG 结构。

但是据说 TranslateMessage 将虚拟击键转换为字符并将它们发送回调用者线程的消息队列。

DispatchMessage 指示操作系统调用相应目标窗口的 Windows Procedure。

两个疑惑:

1) TranslateMessage 的确切功能是什么;是否只是将虚拟击键转换为字符消息(我假设虚拟击键是字母和数字以外的击键),如果字符消息被回发到队列,则不是循环坏了?

2)鼠标事件呢?是直接派发的吗?

最佳答案

是的,当您的消息循环看起来像那样时,您必须调用 TranslateMessage() 是没有意义的。但这不是规范的 Petzold 消息循环的样子:

while (GetMessage(&msg, NULL, 0, 0))
{
    if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

加速器在这里很重要,也称为“快捷键”。无论哪个窗口具有焦点,您的程序都希望响应它们。如 F1 显示程序的帮助文件,而不管哪个控件有焦点。您不希望必须编写子类化每个控制窗口的代码来识别 F1。

因此,如果它是一个快捷键,那么您不想调用 TranslateMessage。如果键恰好与键入键匹配,则该键不应产生 WM_CHAR 消息。这就是为什么它是一个单独的调用。

关于windows - 究竟为什么是 TranslateMessage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12581889/

相关文章:

Windows 8.1 : "IsUserAnAdmin" returns false even though UAC is off and the user a member of "administrators"

windows - VBScript当前目录+子目录?

c++如何在非管理员帐户下获取%AppData%路径并以管理员身份运行VS2013

windows - 当应用程序为64位并使用MSVC2012或MSVC2013进行编译时,ASIO在Windows 8下崩溃

c++ - 无法使用Qt打开文件: “No such file or directory”

c++ - 指针在删除它并在 C++ 中再次分配新内存后是否获得相同的内存地址?

windows - fopen 使用 unicode 文件名

windows - 如何在 Windows 中运行 json-server?

c++ - 自定义 WinCE 6.0 对话框中的标题栏(颜色、文本、图标等)

c - RegQueryValue 失败但 RegQueryValueEx 返回一个值