c++winapiopenglwaitformultipleobjects

Win32 Main Message Loop for OpenGL


My main message loop in a Win32 OpenGL application looks like this:

// 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 );
    }
}

It works almost fine, I have only one problem: if I press Alt+F4 to close the window, it does not quit right after I release the key, however, if I hover the mouse over the window, it quits instantly.

A) Why is this? How should I modify my loop?

B) The original code I found did not use MsgWaitForMultipleObjects but called RenderFrame continuously. I think this way too much CPU time is wasted on redrawing the screen. Am I right? What is the usual way, do you spend all your excess capacity on drawing?


Solution

  • your error that you call PeekMessage only once per WAIT_OBJECT_0 but you need run it in loop while (::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE )) because we can have several messages here. and better use MsgWaitForMultipleObjectsEx instead - try this code:

    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 );
        }
    }
    

    if I press Alt+F4 to close the window, it does not quit right after I release the key

    several messages posted to your thread queue when you press Alt+F4, MsgWaitForMultipleObjects return, but you process not all it but only one

    however, if I hover the mouse over the window, it quits instantly

    new messages (WM_MOUSEMOVE) placed, but main MsgWaitForMultipleObjects again return and you at the end process all messages related to close process