21

Using windows MFC C++. I have a third party app that calls a user-defined method in my CWinApp derived class. This method is called after InitInstance(). If there is an error in this method, such that an exception is thrown and caught in a try/catch block, I would like to exit the application from the catch block. What is the canonical and correct way to quit?

UPDATE:

Serge I believe is right that in InitInstance() returning false is the correct way to quit the application. However, now suppose I want to quit from a CDialog derived class's OnInitDialog() handler, what's the correct way to do that.

UPDATE 2

For me, I found calling PostMessage(WM_CLOSE) to be the best way from my non-modal CDialog derived class. All other methods of quitting I tried would raise some exception or other in some circumstances.

Here's an example of how I use it:

BOOL SomeDialog::OnInitDialog()
{
    CDialog::OnInitDialog();

    ::OleInitialize(nullptr);

    try
    {
        // ...load settings file here
    }
    catch(...)
    {
        PostMessage(WM_CLOSE);
        return TRUE;
    }

    // return TRUE  unless you set the focus to a control
    return TRUE;
}
User
  • 62,498
  • 72
  • 186
  • 247

3 Answers3

35

In InitInstance()

Exiting the app while you are still in InitInstance(): Simply return FALSE from InitInstance().

In the main message loop

It's another story though if you are already in the message loop: The standard way to close an app is to exit the message loop:

PostQuitMessage(0), as its name implies, posts a WM_QUIT message. The message loop reacts by exiting the loop and closing the program.

But you shouldn't simply do that: You should close the opened windows in your app. Assuming you have only your main window, you should destroy it by calling

m_pMainWindow->DestroyWindow();

MFC will react by PostQuitMessage() for you, hence exit the main message loop and close your app.

Better yet, you should post a WM_CLOSE to let your main window close gracefully. It may for example decide to save the current document. Beware though: the standard OnClose() handler may prompt user to save dirty documents. User can even cancel the close action using this prompt (Save document? Yes, No, Cancel).

Destroying the main window will post a WM_DESTROY message to it. MFC reacts by calling PostQuitMessage(0) to exit the message pump. (Actually, MFC does the call in OnNcDestroy() since WM_NCDESTROY which is the absolute last mesage received by a window)

Dialog-based app

Call EndDialog(-1); // Or replace -1 by IDCANCEL, whatever

This call, as you probably know, will close the dialog.

Note that the main dialog of dialog-based app executes in InitInstance(). Closing the dialog will simply exit InitInstance(), which always returns FALSE in such projects.

Serge Wautier
  • 21,494
  • 13
  • 69
  • 110
  • zadane just left you a comment in the form of an answer. I really think StackOverflow's policy to prevent you from leaving a comment until you get 50 rep is bone-headed. – Mark Ransom Sep 27 '11 at 21:44
  • Funny story about WM_DESTROY: http://blogs.msdn.com/b/oldnewthing/archive/2011/09/26/10216420.aspx – Mark Ransom Sep 29 '11 at 20:57
  • In my case, the Dialog does not execute in InitInstance(). Instead it executes in method defined on my CWinApp subclass called by a 3rd party application (my application is a plugin). – User Sep 30 '11 at 00:49
  • @Serge - appTranslator: What I'm doing now to close is calling PostMessage(WM_CLOSE) in my OnInitDialog() handler if there's an error; is that wrong? What's the difference between PostMessage(WM_CLOSE)and calling EndDialog? – User Oct 04 '11 at 18:00
  • My anecdotal evidence for MFC MDI Applications suggest that PostMessage(WM_CLOSE) can create Windows APPCRASH lockups and also Wine has some issues (sometimes won't quit). For me using PostQuitMessage(0) was the better alternative (no APPCRASH so far and under Wine the programs quit as expected) – Oliver Zendel Jun 24 '14 at 13:24
  • +1 for providing detail. It's a complicated area so I appreciated knowing the correct approach, which in my case was to use `m_pMainWindow->DestroyWindow();` because I'm already closing all documents and exiting silently after an automation process completes. – Aranda Feb 27 '15 at 06:13
  • 1
    @OliverZendel: [Why is there a special PostQuitMessage function?](http://blogs.msdn.com/b/oldnewthing/archive/2005/11/04/489028.aspx) – IInspectable Sep 19 '15 at 12:56
  • @IInspectable Sep: Thanks, so PostQuitMessage(0) sets a special flag that will return a WM_QUIT after everything has settled down while PostMessage(..) will actually insert the message in the queue – Oliver Zendel Sep 22 '15 at 15:59
12

Simply use:

PostQuitMessage(0);

Keep in mind your program won't quit instantly from this call, the window/program will receive a WM_QUIT message and then your program will quit.

leetNightshade
  • 2,673
  • 2
  • 36
  • 47
  • 1
    It's the other way around: WM_CLOSE, destroys the window. Upon destrcution of the main window, MFC will then PostQuitMessage(0), which will, as its name implies post a WM_QUIT, which results in exiting the message loop. – Serge Wautier Sep 27 '11 at 12:10
3

Serge - your answer is unfortunately not the best way to do it. PostQuitMessage(0) is the way to go and MFC will destroy the windows for you. You should avoid calling m_pMainWindow->DestroyWindow() directly.

zar
  • 11,361
  • 14
  • 96
  • 178
  • Read the [docs about PostQuitMessage()](http://msdn.microsoft.com/en-us/library/windows/desktop/ms644945(v=vs.85).aspx). – Serge Wautier Sep 29 '11 at 20:47
  • 1
    The document doesn't say anywhere I am incorrect. DestroyWindow() is virtual function which is called by MFC for you when you tell it to close the window by posting the message. It is best to leave it to MFC to do that for you than calling it directly because usually there is sequence of events that occurs when destroying a window and MFC handles it. In some cases we can call it directly if we know what we are doing. – zar Sep 30 '11 at 18:36
  • Where did you see that calling PostQuitMessage() will either close or destroy your window? – Serge Wautier Oct 20 '11 at 21:21
  • 1
    You can see the documentation of PostQuiteMessage(). Obviously posting WM_CLOSE will also do. My suggestion is to post a message to the window to close rather than destroying it directly. For once it is the same process an application ends itself anyways but some expert has given me -1 for it! – zar Oct 24 '11 at 14:19
  • OK, let me rephrase my question: Where, in the PostQuitMessage() docs, did you see that the API will either close or destroy your window? I ask because you told me to read those docs. So I read them. And I don't see any clue whatsoever about your statement. However, those docs ([link](http://msdn.microsoft.com/en-us/library/windows/desktop/ms644945(v=vs.85).aspx)) clearly says: "It is typically used **in response** to a WM_DESTROY message" (emphasis mine). – Serge Wautier Oct 24 '11 at 17:48
  • From the same link you referred: "The PostQuitMessage function posts a WM_QUIT message to the thread's message queue and returns immediately; the function simply indicates to the system that the thread is requesting to quit at some time in the future. When the thread retrieves the WM_QUIT message from its message queue, it should exit its message loop and return control to the system. The exit value returned to the system must be the wParam parameter of the WM_QUIT message." This is graceful ending of the app. This mechanism even gives you an opportunity to set in exit code to the system. – zar Oct 24 '11 at 21:15
  • Thanks for quoting docs that don't mention closing or destruction of the window, whether a consequence of PostQuitMessage or not. The graceful character of such an exit is out of the quotes. I therefore take it as being your own interpretation. Which facts back this interpretation is beyond my understanding. Please allow me to strongly disagree. End of the story as far as I'm concerned. – Serge Wautier Oct 25 '11 at 15:08
  • 1
    Read the OP and title of the question. The user asked about how to 'quit an application' but you are focusing on the window. – zar Oct 25 '11 at 17:30