为什么“TranslateMessage”和“DispatchMessage”会分开调用?

时间:2010-06-30 17:58:12

标签: winapi

我见过的大多数Win32主循环的结构都是:

while (GetMessage(&message, NULL, 0, 0) > 0) {
  TranslateMessage(&message);
  DispatchMessage(&message);
}

有人向我指出,MsgWaitForMultipleObjects可用于为主循环添加一些变种。但是,在GetMessageTranslateMessageDispatchMessage之间做某事实际上有用吗?

4 个答案:

答案 0 :(得分:16)

更传统的消息循环如下所示:

while (GetMessage(&msg, 0, 0, 0)) 
{
    if (!TranslateAccelerator(hwndMain, haccel, &msg))
    {
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    } 
}

在发送消息之前,您需要做的事情是一个非常大的提示:捕获应该在窗口看到它们之前特别拦截和处理的消息。键盘快捷键是一个典型的例子,无论哪个窗口都有焦点,都需要检测它们。

任何GUI类库都会使用名为App.PreProcessMessage的虚拟方法公开它,这是一个可以被覆盖的虚函数,因此您的程序可以实现自己的快捷方式等等。

答案 1 :(得分:9)

他们是不同的野兽。

TranslateMessage function

  

将虚拟密钥消息转换为   字符消息。人物   消息将发布到呼叫   线程的消息队列,待读取   下次线程调用   GetMessage或PeekMessage函数。   [...]   TranslateMessage函数没有   修改指向的消息   lpMsg参数。

另一方面,

DispatchMessage将消息发送到窗口过程。

所以DispatchMessage执行处理邮件的实际工作。 TranslateMessage可能会或可能不会向线程队列发布新消息。如果消息被翻译,则会将字符消息发布到线程的消息队列中。

  

TranslateMessage函数没有   修改指向的消息   lpMsg参数。

它们是单独的调用,因此您(程序员)有机会避免TranslateMessage提供的消息转换。

答案 2 :(得分:1)

引用MSDN

中的一个例子
  

您可以通过多种方式修改消息循环。例如,您可以从队列中检索消息,而无需将它们分派到窗口。这对于发布未指定窗口的消息的应用程序很有用。您还可以指示GetMessage搜索特定消息,将其他消息留在队列中。如果您必须暂时绕过消息队列的通常FIFO顺序,这将非常有用。

如果您不需要转换键盘输入控制代码,也可以避免调用Translate消息。

答案 3 :(得分:0)

TranslateMessage()将虚拟键消息转换为字符输入消息。

这是远程机会的单独调用,在某些情况下,您希望为某些虚拟键生成字符输入消息。