以编程方式正确退出MFC应用程序的方法是什么?

21

我正在使用 windows MFC C++。有一个第三方应用程序调用我的CWinApp派生类中的用户定义方法。此方法在InitInstance()之后被调用。如果在此方法中出现错误,例如抛出异常并在try/catch块中捕获,则我希望在catch块中退出应用程序。什么是标准和正确的退出方式?

更新:

我相信Serge正确指出,在InitInstance()中返回false是退出应用程序的正确方式。但是,现在假设我想从CDialog派生类的OnInitDialog()处理程序退出,应该如何操作?

更新2:

对于我而言,我发现在我的非模态CDialog派生类中调用PostMessage(WM_CLOSE)是最好的退出方式。我尝试过的所有其他退出方法在某些情况下都会引发某些异常。

以下是我使用它的示例:

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;
}

啊!这是一个基于对话框的应用程序。看看我的修改过的答案。 - Serge Wautier
3个回答

35

In InitInstance()

如果在 InitInstance() 中退出应用程序:只需从InitInstance()返回FALSE即可。

在主消息循环中

但如果已经在消息循环中,情况就不同了:关闭应用程序的标准方法是退出消息循环:

PostQuitMessage(0),顾名思义,会发布一个 WM_QUIT 消息。消息循环通过退出循环并关闭程序来做出反应。

但你不应该简单地这样做:你应该关闭打开的窗口。假设你只有一个主窗口,则应通过调用销毁它:

m_pMainWindow->DestroyWindow();

MFC会通过PostQuitMessage()来响应退出,从而退出主消息循环并关闭应用程序。

更好的做法是发送WM_CLOSE以使您的主窗口平滑地关闭。例如,它可以决定保存当前文档。但请注意:标准的OnClose()处理程序可能会提示用户保存脏文档。用户甚至可以使用此提示取消关闭操作(保存文档?是,否,取消)。

销毁主窗口将向其发送WM_DESTROY消息。MFC通过调用PostQuitMessage(0)来退出消息泵。(实际上,MFC在OnNcDestroy()中进行呼叫,因为WM_NCDESTROY是窗口接收到的绝对最后一个消息)

基于对话框的应用程序

调用EndDialog(-1); //或者用IDCANCEL代替-1

如您所知,这个调用将关闭对话框。

请注意,基于对话框的应用程序的主对话框在InitInstance()中执行。关闭对话框将简单地退出InitInstance(),该函数在此类项目中始终返回FALSE


zadane刚刚以回答的形式给你留了一条评论。我真的认为StackOverflow的政策,在你获得50个声望之前阻止你留下评论是愚蠢的。 - Mark Ransom
有一个关于WM_DESTROY的有趣故事:http://blogs.msdn.com/b/oldnewthing/archive/2011/09/26/10216420.aspx - Mark Ransom
+1 是为了提供详细信息。这是一个复杂的领域,所以我很感激知道正确的方法,对我来说是使用 m_pMainWindow->DestroyWindow();,因为我已经在自动化过程完成后关闭了所有文档并静默退出。 - Aranda
@IInspectable Sep:谢谢,所以PostQuitMessage(0)设置了一个特殊标志,在一切都安定下来后将返回WM_QUIT,而PostMessage(..)实际上会将消息插入队列中。 - Oliver Zendel
显示剩余3条评论

12

简单地使用:

PostQuitMessage(0);

请记住,您的程序不会立即从此调用中退出,窗口/程序将接收到WM_QUIT消息,然后您的程序将退出。


1
正相反,WM_CLOSE 销毁窗口。在主窗口被销毁后,MFC 将会发送 PostQuitMessage(0),它的名字意味着发送一个 WM_QUIT,导致退出消息循环。 - Serge Wautier

3

Serge - 你的答案不是最好的方法。PostQuitMessage(0) 是正确的方式,MFC会帮您销毁窗口。您应该避免直接调用 m_pMainWindow->DestroyWindow()。


阅读关于PostQuitMessage()的文档:http://msdn.microsoft.com/en-us/library/windows/desktop/ms644945(v=vs.85).aspx。 - Serge Wautier
1
文档中没有任何地方说我是错误的。DestroyWindow()是一个虚函数,当您通过发布消息告诉MFC关闭窗口时,MFC会为您调用它。最好让MFC为您处理这个过程,而不是直接调用它,因为通常在销毁窗口时会发生一系列事件,而MFC会处理它们。在某些情况下,如果我们知道自己在做什么,我们可以直接调用它。 - zar
1
您可以查看PostQuitMessage()的文档。显然,发送WM_CLOSE也能起到同样的作用。我的建议是向窗口发布消息以关闭它,而不是直接销毁它。因为这样一来,应用程序结束自身对于操作系统来说是相同的过程,但有些专家却为此给了我-1分! - zar
感谢您引用文档,但其中并未提及窗口的关闭或销毁,无论是由PostQuitMessage引起的还是其他原因。这种优雅退出的特性并不在引用范围内。因此,我认为这是您自己的解释。支持这种解释的事实超出了我的理解范围。请允许我强烈反对。就我而言,这件事就结束了。 - Serge Wautier
1
阅读问题的原始帖和标题。用户询问如何“退出应用程序”,但您正在关注窗口。 - zar
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接