代码之家  ›  专栏  ›  技术社区  ›  Stéphan Kochen

为什么“TranslateMessage”和“DispatchMessage”是分开的呼叫?

  •  19
  • Stéphan Kochen  · 技术社区  · 14 年前

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

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

    有人向我指出 MsgWaitForMultipleObjects 可用于向主循环添加一些变体。但是,有没有一种情况是 GetMessage , TranslateMessage DispatchMessage 真的有用吗?

    4 回复  |  直到 12 年前
        1
  •  20
  •   Hans Passant    14 年前

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

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

    这是一个相当大的提示,提示您在发送消息之前应该做什么:捕获应该在窗口看到它们之前被截获并进行特殊处理的消息。键盘快捷键是一个典型的例子,无论哪个窗口有焦点,都需要检测到它们。

    任何GUI类库都会用一个名为App.PreProcessMessage的虚拟方法来公开它,这个虚拟函数可以被重写,这样你的程序就可以实现自己的快捷方式等等。

        2
  •  11
  •   Community SqlRyan    10 年前

    为了 TranslateMessage function

    将虚拟密钥消息转换为 消息已发布到呼叫中心 线程的消息队列,要读取 GetMessage或PeekMessage函数。 [...] TranslateMessage函数不存在 修改 lpMsg参数。

    DispatchMessage

    DispatchMessage 处理消息的实际工作。 TranslateMessage 可以或不可以将新消息发布到线程队列。如果消息被翻译,那么一个字符消息被发布到线程的消息队列中。

    TranslateMessage函数不存在 lpMsg参数。

    它们是独立的调用,因此程序员可以有机会避免 翻译信息 .

        3
  •  2
  •   bdonlan    14 年前

    好吧,举一个例子 MSDN :

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

        4
  •  1
  •   shoosh    14 年前

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

    这是一个单独的呼吁,为遥远的机会,在某些情况下,你会想 为某些虚拟键生成字符输入消息。