What is the correct way to programmatically quit an MFC application?
使用Windows MFC C ++。 我有一个第三方应用程序,该应用程序在CWinApp派生类中调用用户定义的方法。 在InitInstance()之后调用此方法。 如果此方法有错误,则在try / catch块中引发并捕获了异常,我想从catch块退出应用程序。 规范和正确的退出方式是什么?
更新:
我相信Serge是正确的,在InitInstance()中返回false是退出应用程序的正确方法。 但是,现在假设我想从CDialog派生类的OnInitDialog()处理函数中退出,执行此操作的正确方法是什么。
更新2
对我来说,我发现从非模态CDialog派生类中调用PostMessage(WM_CLOSE)是最好的方法。 我尝试过的所有其他退出方法都会在某些情况下引发某些异常或其他情况。
这是我的用法示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 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;
} |
-
啊! 它是一个基于对话框的应用程序。 看到我编辑的答案。
在InitInstance()中
仍在InitInstance()中时退出应用程序:只需从InitInstance()返回FALSE。
在主消息循环中
但是,如果您已经处于消息循环中,则这是另一个故事:关闭应用程序的标准方法是退出消息循环:
顾名思义,PostQuitMessage(0)发布WM_QUIT消息。消息循环通过退出循环并关闭程序来作出反应。
但是,您不应该简单地这样做:您应该关闭应用程序中打开的窗口。
假设您只有主窗口,则应通过调用来销毁它
1
| m_pMainWindow->DestroyWindow(); |
MFC将通过PostQuitMessage()为您做出反应,因此退出主消息循环并关闭您的应用程序。
更好的是,您应该发布WM_CLOSE以使主窗口正常关闭。例如,它可能决定保存当前文档。但是要当心:标准的OnClose()处理程序可能会提示用户保存脏文档。用户甚至可以使用此提示取消关闭操作(保存文档?是,否,取消)。
销毁主窗口将向其中发布WM_DESTROY消息。 MFC通过调用PostQuitMessage(0)退出退出消息泵。 (实际上,由于WM_NCDESTROY是窗口接收到的绝对最后一条消息,因此MFC在OnNcDestroy()中进行调用)
基于对话框的应用
调用EndDialog(-1); //或用IDCANCEL代替-1
您可能知道,此调用将关闭对话框。
请注意,基于对话框的应用程序的主对话框在InitInstance()中执行。关闭对话框将仅退出InitInstance(),在此类项目中,该值始终返回FALSE。
-
zadane刚刚以答案的形式给您留下了评论。我真的认为StackOverflows政策会阻止您发表评论,直到获得50个代表。
-
关于WM_DESTROY的有趣故事:blogs.msdn.com/b/oldnewthing/archive/2011/09/26/10216420.aspx
-
就我而言,对话框不会在InitInstance()中执行。而是在由第三方应用程序(我的应用程序是插件)调用的CWinApp子类上定义的方法中执行。
-
@Serge-appTranslator:我现在要关闭的操作是在发生错误时在OnInitDialog()处理函数中调用PostMessage(WM_CLOSE);那是错的吗? PostMessage(WM_CLOSE)和调用EndDialog之间有什么区别?
-
我关于MFC MDI应用程序的轶事证据表明,PostMessage(WM_CLOSE)可以创建Windows APPCRASH锁定,并且Wine也存在一些问题(有时不会退出)。对我来说,使用PostQuitMessage(0)是更好的选择(到目前为止,尚无APPCRASH,在Wine下,程序按预期退出)
-
+1用于提供详细信息。这是一个复杂的领域,所以我很高兴知道正确的方法,在我的情况下,该方法是使用m_pMainWindow->DestroyWindow();,因为Im已经关闭了所有文档,并在自动化过程完成后以静默方式退出。
-
@OliverZendel:为什么会有特殊的PostQuitMessage函数?
-
@IInspectable Sep:谢谢,所以PostQuitMessage(0)设置了一个特殊标志,当一切都解决之后,它将返回WM_QUIT,而PostMessage(..)实际上会将消息插入队列中
只需使用:
请记住,您的程序不会立即从此调用中退出,窗口/程序将收到WM_QUIT消息,然后您的程序将退出。
-
反之亦然:WM_CLOSE,销毁窗口。销毁主窗口后,MFC将随后PostQuitMessage(0),顾名思义,它将发布WM_QUIT,这将导致退出消息循环。
Serge-不幸的是,您的答案并不是最好的方法。 PostQuitMessage(0)是解决方法,MFC会为您破坏窗户。您应该避免直接调用m_pMainWindow-> DestroyWindow()。
-
阅读有关PostQuitMessage()的文档。
-
该文件没有说我不正确的地方。 DestroyWindow()是虚函数,当您通过发布消息告诉它关闭窗口时,MFC将为您调用该函数。与直接调用它相比,最好将它留给MFC为您完成,因为通常在销毁窗口并由MFC处理时会发生一系列事件。在某些情况下,如果我们知道自己在做什么,我们可以直接调用它。
-
您在哪里看到调用PostQuitMessage()会关闭或破坏您的窗口?
-
您可以查看PostQuiteMessage()的文档。显然,发布WM_CLOSE也可以。我的建议是将消息发布到窗口以关闭而不是直接销毁它。因为一旦是相同的过程,应用程序无论如何都会自行结束,但是有些专家为此给了我-1!
-
好的,让我重新表达一下我的问题:在PostQuitMessage()文档中,您在哪里看到API会关闭或破坏您的窗口?我问是因为您叫我阅读那些文档。所以我读了他们。而且我看不出您的陈述有任何线索。但是,这些文档(链接)明确指出:"通常用于响应WM_DESTROY消息"(强调我的)。
-
在您引用的同一链接中:" PostQuitMessage函数将WM_QUIT消息发布到线程消息队列中并立即返回;该函数只是向系统指示该线程正在请求将来某个时候退出。当该线程检索到WM_QUIT消息从其消息队列中退出,它应该退出其消息循环并将控制权返回给系统。返回到系统的退出值必须是WM_QUIT消息的wParam参数。"这是应用的优美结尾。这种机制甚至使您有机会在系统中设置退出代码。
-
感谢您引用不提及关闭或销毁窗口的文档,无论是否为PostQuitMessage所致。 这种退出方式的优美特征不在引号中。 因此,我认为这是您自己的解释。 这种解释背后的事实是我无法理解的。 请允许我强烈不同意。 就我而言,故事的结尾。
-
阅读操作说明和问题标题。 用户询问有关如何退出应用程序的信息,但是您正在关注窗口。