Winapi 为什么是;“翻译信息”;及;“发送消息”;单独通话?

Winapi 为什么是;“翻译信息”;及;“发送消息”;单独通话?,winapi,Winapi,我见过的大多数Win32主循环的结构如下: while (GetMessage(&message, NULL, 0, 0) > 0) { TranslateMessage(&message); DispatchMessage(&message); } 有人向我指出,它可以用来为主循环添加一些变化。但是,有没有一种情况是,在和之间做点什么实际上是有用的呢?它们是不同的野兽 为了 将虚拟密钥消息转换为 字符信息。人物 消息被发布到呼叫中心 线程的消息队列,要读

我见过的大多数Win32主循环的结构如下:

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

有人向我指出,它可以用来为主循环添加一些变化。但是,有没有一种情况是,在和之间做点什么实际上是有用的呢?

它们是不同的野兽

为了

将虚拟密钥消息转换为 字符信息。人物 消息被发布到呼叫中心 线程的消息队列,要读取 下次线程调用 GetMessage或PeekMessage函数。 [...] TranslateMessage函数不起作用 修改所指向的消息 lpMsg参数

另一方面,向窗口过程发送消息

因此,
DispatchMessage
执行处理消息的实际工作
TranslateMessage
可能会也可能不会向线程队列发布新消息。如果消息已翻译,则会将字符消息发布到线程的消息队列

TranslateMessage函数不起作用 修改所指向的消息 lpMsg参数

它们是单独的调用,因此程序员有机会避免由
TranslateMessage

TranslateMessage()
将虚拟键消息转换为字符输入消息所提供的消息转换


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

请引用以下示例:

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


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

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

while (GetMessage(&msg, 0, 0, 0)) 
{
    if (!TranslateAccelerator(hwndMain, haccel, &msg))
    {
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    } 
}
这是一个相当大的提示,告诉您在发送消息之前要做什么:捕获应该在窗口看到它们之前被截获并进行特殊处理的消息。键盘快捷键是一个典型的例子,无论哪个窗口有焦点,都需要检测到它们


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

在消息被翻译后,虚拟键消息仍然会通过DispatchMessage发送吗?@JeroenBollen Yes,因为
TranslateMessage
将翻译结果推送到消息队列上,而不是修改传递给它的消息。因此,翻译版本和虚拟密钥原件都被发送。如果我多次翻译和发送一条消息,或者根本不翻译和发送消息,可以吗?-我已经测试过了,没有发现任何问题,但我只是想确保它真的没有问题。