2018年5月21日 星期一

Win32的Gameloop的滑順問題(2)

Win32的Gameloop的滑順問題(2)

前言

  還記得前一篇裡Win32的Gameloop的滑順問題(1)有個沒解決的問題嗎?就是會有一個20mSecs的MSG的問題,這裡找到答案了,在此做個紀錄。

內容

  在Win32的Gameloop裡的接收視窗訊息的程式碼如下
while( true ) {
    if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {
        if ( WM_QUIT == msg.message ) {
            break;
        } else {
            TranslateMessage( &msg);
            DispatchMessage( &msg);
        }
    } else {
        gameloop();
    }
}

裡面的PeekMessage()的第二個參數是NULL,接著看PeekMessage的說明,會發現當第二個參數是NULL時,會接收所有的訊息,所以將第二個參數改成主要的視窗後,發現那一個20mSecs的MSG遽然不見了!本以為事情這樣就解決了,但當按下視窗右上角的叉叉後,程式會變得無法關閉,原因是WM_QUIT這個MSG再也收不到了,所以當按下叉叉後,迴圈並能正常跳出,解決的程式碼如下
bool isAppRun=true;//global var...
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    PAINTSTRUCT ps;
    HDC hdc;
    switch( message )
    {
        case WM_PAINT:
            hdc = BeginPaint( hWnd, &ps );
            EndPaint( hWnd, &ps );
            break;

        case WM_DESTROY:
            PostQuitMessage( 0 );
            isAppRun= false;
            break;

        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
    }

    return 0;
}
//...
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )
{
  //...
  //
  while( WM_QUIT != msg.message && isAppRun)
  {
    if( PeekMessage( &msg, hWnd, 0, 0, PM_REMOVE ) )
    {
      TranslateMessage( &msg );
      DispatchMessage( &msg );
    }
    else
    {
      gameloop();
    }
  }
}

新增一個isAppRun,在WndProc裡處理WM_DESTROY裡設為false,接著按下叉叉後就可以順利跳出迴圈了。

參考資料

PeekMessage

沒有留言:

張貼留言