Question

I'm working on a Windows game, and I have this:

bool game_cont;

LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
    case WM_QUIT: case WM_CLOSE: case WM_DESTROY: game_cont = false; break;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}

int WINAPI WinMain(/*lots of parameters*/)
{
    //tedious initialization

    //game loop
    while(game_cont)
    {
        //give message to WinProc
        if(!GameRun()) game_cont = false;
    }
    return 0;
}

and I am wondering if there is a better way to do this (ignoring timers &c. for right now) than to have game_cont be global. In short, I need to be able to exit the while in WinMain from WinProc, so that if the user presses the closes out of the game in a way other that the game's in game menu, the program wont keep running in memory. (As it did when I tested this without the game_cont.. statement in WinProc.

Oh, and on a side note, GameRun is basically a bool that returns false when the game ends, and true otherwise.

Was it helpful?

Solution

Yes, use PeekMessage, it's the standard in game development.

This is the best approach, I believe:

int Run()
{
    MSG msg;
    while(true)
    {
        if(::PeekMessage(&msg,0,0,0 PM_REMOVE))
        {
            if(msg.message == WM_QUIT || 
                       msg.message == WM_CLOSE || 
                       msg.message == WM_DESTROY)
                break;

            ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);           
        }
        else
        {
            //Run game code
                    if(!GameRun())
                         break;
        }
    }
} 

Also, look at this (specially the first answer)

OTHER TIPS

You could use exit. Use atexit to make sure that WM_CLOSE gets to the message que when its time to exit.

I don't know what's the ultimate design here, but it's an idea.

You could make game_cont static to your main file which has WinMain/WinProc, but I don't know of a significantly better structure.

No, don't do that.

WM_QUIT is your flag. GetMessage return value indicates when WM_QUIT is encountered.

Your main window will never receive WM_QUIT, as it isn't sent to a window. WM_CLOSE will call DestroyWindow by default, so you don't need any special handling for that. Handle WM_DESTROY by calling PostQuitMessage, which results in WM_QUIT on your thread, the special return value from GetMessage, and stops your message dispatch loop.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top