2

I have a problem with WM_ENDSESSION message. Namely I would like to exit from the main loop of the application (WindowProc) when the WM_ENDSESSION message is sending... So, I wrote something like that:

LRESULT CALLBACK windowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
    //...       
    case WM_QUERYENDSESSION: return TRUE;       
    case WM_ENDSESSION: 
         if(wParam) PostQuitMessage(0);         
    break;    
    default:
        return DefWindowProc(hwnd,msg,wParam,lParam);
    }

    return 0;
}

..., but it doesn't work - application doesn't exit the main loop...

I read about WM_QUERYENDSESSION and WM_ENDSESSION on msdn, but I couldn't find any helpful information...

Any idea, where is the mistake?

Jeff Yates
  • 61,417
  • 20
  • 137
  • 189
malan
  • 21
  • 1
  • 2
  • 1
    Funny, I've noticed the same, and I thought it was just me. My goal was to save data and exit gracefully upon receiving WM_QUERYENDSESSION/WM_ENDSESSION, though my program never saved anything, ever. It was always killed cold. – Damon Apr 20 '11 at 18:25
  • Show your event loop code. I guess it is in your `main` function. – Serge Dundich Apr 20 '11 at 18:46
  • BTW How you are trying to trigger the WM_QUERYENDSESSION/WM_ENDSESSION event? Shutdown? Logoff? Is your `windowProc` the window procedure of a top-level window? – Serge Dundich Apr 20 '11 at 18:53
  • @Damon: Of course I would put PostQuitMessage in WM_QUERYENDSESSION, but it's incorrect solution... @Serge Dundich: Yes, my loop is in the `main`: int main() { // Init window... MSG event; while( GetMessage(&event,0,0,0) ) { TranslateMessage(&event); DispatchMessage(&event); } //... return event.wParam; } > How you are trying to trigger the WM_QUERYENDSESSION/WM_ENDSESSION event? Log off. – malan Apr 20 '11 at 19:05
  • is it even landing at your handler for WM_ENDSESSION? I bet it isn't. – David Heffernan Apr 20 '11 at 19:11
  • @m.m.m: OK. So one question remains: Is your `windowProc` the window procedure of a top-level window? And another: Have you tried to debug your `windowProc`? – Serge Dundich Apr 20 '11 at 19:16
  • I created a log file which contain: "Start... WM_QUERYENDSESSION WM_ENDSESSION" ...when I'm logging off. And: "Start... WM_CLOSE WM_DESTROY End..." ...when I close application by normally... windowProc is the procedure of my main (and only) window. – malan Apr 20 '11 at 19:48

3 Answers3

3

I don't think it's wrong to call PostQuitMessage in response to WM_QUERYENDSESSION.

WM_ENDSESSION is the end of the world. It's too late at that point to postpone work until a later time (calling PostQuitMessage). Do it now, or you'll never get a chance to do it. Also, consider what you are doing. As Raymond Chen once put it, "[cleaning up your app in response to WM_ENDSESSION is] like taking the time to steam-clean the rugs before you demolish the building. Wasted effort."

WM_QUERYENDSESSION grants your window a last-chance to interact with the user. You have decided on behalf of the user that your app will die and you want to gracefully exit, so this is your last opportunity to schedule it.

Updated

I don't know that will even work to PostQuitMessage in response to WM_QUERYENDSESSION. The MSDN docs state, "The WM_ENDSESSION message is sent to an application after the system processes the results of the WM_QUERYENDSESSION message."

Sent implies that the message pump doesn't get a crack at messages. Of course, even the doc authors often confuse sent and posted.

Tergiver
  • 14,171
  • 3
  • 41
  • 68
  • That's a misquotation. I think perhaps you're mixing up [this](http://blogs.msdn.com/b/oldnewthing/archive/2008/04/21/8413175.aspx) with [this](http://blogs.msdn.com/b/oldnewthing/archive/2012/01/05/10253268.aspx). – Harry Johnston Jul 13 '15 at 08:05
1

You don't need any special handling. Just call DefWindowProc instead of handling these messages.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
-1

I would put

switch(msg)
{
    //...  
    case WM_ENDSESSION:  
        if(wParam) PostQuitMessage(0);  
        return 0;  
    //...  
}

putting return 0; should exit the program, if you are in the main() function

Nate Koppenhaver
  • 1,676
  • 3
  • 21
  • 31
  • 2
    this isn't how to run a message loop. If you are going to exit from main why bother posting a quit message that you are never going to retrieve because you just abandoned ship. – David Heffernan Apr 20 '11 at 18:50