2017-01-25 8 views
-4

Мой главный цикл обработки сообщений в приложении Win32 OpenGL выглядит следующим образом:Win32 Main Message Loop для 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 непрерывно. Я думаю, что слишком много времени процессора тратится на перерисовку экрана. Я прав? Как обычно, тратите ли вы лишнюю емкость на рисование?

+0

Пожалуйста, покажите реальный код. Цикл 'while (bQuit)' никогда не запускается. – IInspectable

+0

Не похоже, что у нас достаточно кода. И этот код не реален. Цикл никогда не будет выполняться. –

+0

@IInspectable - как насчет 'if (msg.message == WM_QUIT) bQuit = true;'? это и разрыв петли – RbMm

ответ

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) размещены, но главное MsgWaitForMultipleObjects снова вернуться и вас в конце процесса все сообщения, относящиеся закрыть процесс

+0

'GetMessage' тоже делает то же самое правильно? – Raindrop7

+1

@ Raindrop7 no конечно - мы не можем использовать 'GetMessage' здесь, потому что это синхронный может ** ждать **. нам нужно использовать ** только ** 'PeekMessage' и в цикле while true – RbMm