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?
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