Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

My Win32 application won't exit the main loop

Tags:

c

windows

winapi

This is my main loop:

    while(TRUE)
    {

    PeekMessage(&msg,hWnd,0,0,PM_REMOVE);
        if (msg.message==WM_QUIT)
            break;
        TranslateMessage(&msg);
        DispatchMessage(&msg);


    }

and this is my callback procedure:

 LRESULT CALLBACK WinProc(HWND hWnd,UINT msg1,WPARAM wParam,LPARAM lParam)
 {
    switch(msg1)
    {
        case WM_DESTROY  :
        {
            PostQuitMessage(0);
            return 0;
        }
        break;
    }

    return DefWindowProc(hWnd,msg1,wParam,lParam);
}

I found out that when I press Close button WM_NCLBUTTONDOWN will be returned by the PeekMessage function in the next loop, and no WM_QUIT!

like image 300
The Pianist Avatar asked May 29 '12 19:05

The Pianist


2 Answers

The correct way to do a message loop is

BOOL bRet;
MSG msg;
while ((bRet = GetMessage(&msg, hWnd, 0, 0)) != 0)
{ 
    if (bRet == -1)
    {
        // handle the error and possibly exit
    }
    else
    {
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    }
}

You can use PeekMessage if you really need to... but why are you ignoring the return value?

Also, note that this is specific to a window. I believe PostQuitMessage is for a thread... I don't remember it off the top of my head, but you might need to pass NULL instead of hWnd.

If you have any other windows, that may hijack their message loop as well -- I don't think it's usually an issue, but it might potentially be one; keep that in mind.

like image 68
user541686 Avatar answered Nov 12 '22 05:11

user541686


Here's some code I found. It should give you something to work with.

    // Main message loop:
do
{
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    // Run game code here.
    gTradeApp->ExecuteNextAction();
}
while (msg.message != WM_QUIT);

and the WndProc

LRESULT CALLBACK WndProc(HWND aHWnd, UINT aMessage, WPARAM aWParam, LPARAM aLParam)
{
    switch (aMessage)
    {
    case WM_COMMAND:
        return HandleCommand(aHWnd, aMessage, aWParam, aLParam);

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(aHWnd, aMessage, aWParam, aLParam);
    }

    return 0;
}
like image 2
James Avatar answered Nov 12 '22 04:11

James