-4

我在 Win32 OpenGL 应用程序中的主要消息循环如下所示:

// Inside wWinMain
bool bQuit = false;
while( bQuit == false )
{
    DWORD dwReturn = ::MsgWaitForMultipleObjects( 0, NULL, FALSE, 12, QS_ALLINPUT );

    if( dwReturn == WAIT_OBJECT_0 )
    {
        MSG msg;
        BOOL bReturn = ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE );
        if( bReturn != FALSE )
        {
            if( msg.message == WM_QUIT )
                bQuit = true;
            ::TranslateMessage( &msg );
            ::DispatchMessage( &msg );
        }
    }

    if( dwReturn == WAIT_OBJECT_0 || dwReturn == WAIT_TIMEOUT )
    {
        RenderFrame();
        ::SwapBuffers( hDc );
    }
}

它几乎可以正常工作,我只有一个问题:如果我按 Alt+F4 关闭窗口,它不会在我释放键后立即退出,但是,如果我将鼠标悬停在窗口上,它会立即退出。

A) 为什么会这样?我应该如何修改我的循环?

B)我发现的原始代码没有使用MsgWaitForMultipleObjects,而是连续调用了RenderFrame。我认为这种方式在重绘屏幕上浪费了太多的 CPU 时间。我对吗?通常的方式是什么,你把所有多余的能力都花在了画画上吗?

4

1 回答 1

3

您每次PeekMessage只调用一次WAIT_OBJECT_0的错误,但您需要循环运行它,while (::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ))因为我们可以在这里有几条消息。并更好地使用MsgWaitForMultipleObjectsEx- 试试这个代码:

bool bQuit = false;
while( !bQuit )// for (;;)
{
    MSG msg;

    switch(::MsgWaitForMultipleObjectsEx( 0, NULL, 12, QS_ALLINPUT, 0))
    {
    case WAIT_OBJECT_0:
        while (::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ))
        {
            if( msg.message == WM_QUIT )
                bQuit = true;// return;
            ::TranslateMessage( &msg );
            ::DispatchMessage( &msg );
        }
    case WAIT_TIMEOUT:
        RenderFrame();
        ::SwapBuffers( hDc );
    }
}

如果我按 Alt+F4 关闭窗口,在我释放键后它不会立即退出

Alt+F4当您按下、MsgWaitForMultipleObjects返回时,有几条消息发布到您的线程队列,但您处理的不是全部,而是只处理一条

但是,如果我将鼠标悬停在窗口上,它会立即退出

放置了新消息(WM_MOUSEMOVE),但 mainMsgWaitForMultipleObjects再次返回,您最后处理与关闭过程相关的所有消息

于 2017-01-25T21:13:57.817 回答