【问题标题】:Win32 message pump, does DispatchMessage() handle entire message queue or just top message?Win32 消息泵,DispatchMessage() 是处理整个消息队列还是仅处理顶部消息?
【发布时间】:2012-10-17 00:30:27
【问题描述】:

所以我一直在阅读 Win32 消息泵,我很好奇 DispatchMessage() 函数是处理整个消息队列,还是只处理队列顶部的消息?

例如,我见过这样的循环:

while(true) 
{

    MSG  msg;

    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        if (msg.message == WM_QUIT) 
        {
            break;
        } 
        else 
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    } 

    do 
    {   
    } while (clock.getTimeDeltaMilliseconds() < 1.66f); // cap at 60 fps

    // run frame code here
}

在此示例中,是否会处理每条消息,或者此循环结构是否会导致每帧仅处理一条消息?

如果它一次只处理一条消息,我是否应该将 if(PeekMessage) 语句更改为 while 循环以确保处理所有消息?:

while(true) 
{

    MSG  msg;

    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        if (msg.message == WM_QUIT) 
        {
            return;
        } 
        else 
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    } 

    do 
    {   
    } while (clock.getTimeDeltaMilliseconds() < 1.66f); // cap at 60 fps

    // run frame code here
}

【问题讨论】:

  • 我已经有 没有做过 Windows 开发了。为什么帧计时码和消息循环在同一个线程?

标签: c++ winapi loops message message-pump


【解决方案1】:

DispatchMesasge与消息队列无关,它只处理你传递给它的消息,从消息队列中删除消息的实际功能是PeekMessage,它只删除或查看一条消息,所以你是对的您应该使用while 循环来处理队列中的所有消息

【讨论】:

    【解决方案2】:

    它只处理最上面的消息。 MSG 是一个包含one 消息信息的结构,当您调用GetMessagePeekMessage 时填充,前者是一个阻塞函数。然后,您将有关一条消息的信息传递给 DispatchMessage

    如果您想在循环中执行任何其他操作之前处理整个消息队列,则应将该部分包含在循环中。

    【讨论】:

    • 所以我可以在我的第二个示例中使用语句 while(PeekMessage(...)) 来遍历队列中的每条消息?这是推荐的方法吗?
    • @Pondwater,您还必须将 TranslateMessageDispatchMessage 调用包含在循环中,以便实际处理从队列中提取的每条消息,而不仅仅是最后一条。我以前见过那里的循环,我会说这是合乎逻辑的,因为滞后用户界面通常是个坏主意。
    猜你喜欢
    • 2015-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-01
    • 1970-01-01
    • 2023-02-10
    • 1970-01-01
    • 2020-02-17
    相关资源
    最近更新 更多