2010-06-30 44 views

回答

16

比较传统的消息循环是这样的:

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

这是一个相当大的提示你想要什么分派消息之前做的事情:那应该被拦截捕获的消息和特殊治疗前窗户看到他们。键盘快捷键是一个典型的例子,无论窗口有什么焦点,都需要检测它们。

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

+0

这是一个很好的实例,谢谢。 :) – 2010-06-30 20:48:09

+1

仅仅需要确认两年后... – 2012-08-30 23:06:41

+0

如果我翻译和发送一条消息不止一次,或者根本不翻译和发送消息,可以吗? - 我已经测试过并没有发现问题,但我只是想确保它确实没有问题。 – 123iamking 2017-04-06 14:18:43

8

它们是不同的野兽。

对于TranslateMessage function

平移虚拟键的信息到 字符消息。字符 消息被发布到调用 线程的消息队列中,待下一次线程调用 GetMessage或PeekMessage函数时读取 。 [...] TranslateMessage函数不会 修改 lpMsg参数指向的消息。

DispatchMessage另一方面,将消息发送到窗口过程。

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

的TranslateMessage函数不 修改消息由 LPMSG参数指向。

它们是分开的调用,所以程序员可以避免由TranslateMessage提供的消息转换。

+0

在翻译完消息后,虚拟键消息是否仍然会由DispatchMessage调度? – 2014-08-06 12:11:50

0

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

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

1

那么从MSDN举一个例子:

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

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