了解从TranslateMessage()发送的字符消息顺序

Understanding the character message ordering sent from TranslateMessage()

本文关键字:字符 消息 顺序 TranslateMessage 了解      更新时间:2023-10-16

下面是一个经典的消息循环。正如MSDN所说,TranslateMessage(const MSG*)确实将虚拟密钥消息(WM_KEYDOWN)转换为字符消息(WM_CHAR)。然后,它将把这个刚刚翻译的WM_CHAR消息发布到线程消息队列中。

AFAIK消息队列应为FIFO结构,当TranslateMessage返回时,消息WM_CHAR将在队列末尾发送。我做了一个实验,同时按下多个键,例如"a"、"s"answers"d"。我放了一个sleep(1000),使这3条WM_KEYDOWN消息在调用TranslateMessage()之前先在消息队列中排队。

while (GetMessage(&msg, NULL, 0, 0))
{
    Sleep(1000) // make message queue receives all the WM_KEYDOWN before Translated                     
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
     print_the_message(uMsg, wParam);
}

我想订单应该是

  • WM_KEYDOWN('a')
  • WM_KEYDOWN
  • WM_KEYDOWN('f')
  • /*睡眠唤醒前排队*/
  • WM_CHAR('a')
  • WM_CHAR
  • WM_CHAR('f')

但是print_the_message实际上显示了这个排序

  • WM_KEYDOWN('a')
  • WM_CHAR('a')
  • WM_KEYDOWN
  • WM_CHAR
  • WM_KEYDOWN('f')
  • WM_CHAR('f')

TranslateMessage创建的字符消息WM_CHAR是否具有特殊的优先级或处理,以使其能够跟随前一条WM_KEYDOWN消息并插队?

文档中强调:

字符消息被发布到调用线程的消息队列中,以便在下次线程调用GetMessage或PeekMessage函数时读取。

这与观察到的行为相匹配。