我见过的大多数Win32主循环的结构都是:
while (GetMessage(&message, NULL, 0, 0) > 0) {
TranslateMessage(&message);
DispatchMessage(&message);
}
有人向我指出,MsgWaitForMultipleObjects
可用于为主循环添加一些变种。但是,在GetMessage
,TranslateMessage
和DispatchMessage
之间做某事实际上有用吗?
答案 0 :(得分:16)
更传统的消息循环如下所示:
while (GetMessage(&msg, 0, 0, 0))
{
if (!TranslateAccelerator(hwndMain, haccel, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
在发送消息之前,您需要做的事情是一个非常大的提示:捕获应该在窗口看到它们之前特别拦截和处理的消息。键盘快捷键是一个典型的例子,无论哪个窗口都有焦点,都需要检测它们。
任何GUI类库都会使用名为App.PreProcessMessage的虚拟方法公开它,这是一个可以被覆盖的虚函数,因此您的程序可以实现自己的快捷方式等等。
答案 1 :(得分:9)
他们是不同的野兽。
另一方面,将虚拟密钥消息转换为 字符消息。人物 消息将发布到呼叫 线程的消息队列,待读取 下次线程调用 GetMessage或PeekMessage函数。 [...] TranslateMessage函数没有 修改指向的消息 lpMsg参数。
DispatchMessage将消息发送到窗口过程。
所以DispatchMessage
执行处理邮件的实际工作。 TranslateMessage
可能会或可能不会向线程队列发布新消息。如果消息被翻译,则会将字符消息发布到线程的消息队列中。
TranslateMessage函数没有 修改指向的消息 lpMsg参数。
它们是单独的调用,因此您(程序员)有机会避免TranslateMessage
提供的消息转换。
答案 2 :(得分:1)
引用MSDN:
中的一个例子您可以通过多种方式修改消息循环。例如,您可以从队列中检索消息,而无需将它们分派到窗口。这对于发布未指定窗口的消息的应用程序很有用。您还可以指示GetMessage搜索特定消息,将其他消息留在队列中。如果您必须暂时绕过消息队列的通常FIFO顺序,这将非常有用。
如果您不需要转换键盘输入控制代码,也可以避免调用Translate消息。
答案 3 :(得分:0)
TranslateMessage()
将虚拟键消息转换为字符输入消息。
这是远程机会的单独调用,在某些情况下,您希望不为某些虚拟键生成字符输入消息。