【问题标题】:What is the correct way to programmatically quit an MFC application?以编程方式退出 MFC 应用程序的正确方法是什么?
【发布时间】:2011-11-25 14:45:16
【问题描述】:

使用 windows MFC C++。我有一个第三方应用程序在我的 CWinApp 派生类中调用用户定义的方法。此方法在 InitInstance() 之后调用。如果此方法中存在错误,例如抛出异常并在 try/catch 块中捕获,我想从 catch 块中退出应用程序。什么是规范且正确的戒烟方式?

更新:

Serge 我认为在 InitInstance() 中返回 false 是正确的退出应用程序的方法。但是,现在假设我想从 CDialog 派生类的 OnInitDialog() 处理程序中退出,那么正确的方法是什么。

更新 2

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

这是我如何使用它的示例:

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

【问题讨论】:

  • 啊!这是一个基于对话框的应用程序。请参阅我编辑的答案。

标签: c++ mfc exit quit


【解决方案1】:

简单使用:

PostQuitMessage(0);

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

【讨论】:

  • 反之亦然:WM_CLOSE,破坏窗口。在主窗口被破坏后,MFC 将 PostQuitMessage(0),顾名思义,它将发布一个 WM_QUIT,从而退出消息循环。
【解决方案2】:

在 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 次代表之前发表评论的政策是愚蠢的。
  • 在我的例子中,对话框不会在 InitInstance() 中执行。相反,它在由第 3 方应用程序(我的应用程序是一个插件)调用的 CWinApp 子类上定义的方法中执行。
  • @Serge - appTranslator: 如果出现错误,我现在要关闭的是在我的 OnInitDialog() 处理程序中调用 PostMessage(WM_CLOSE);那是错的吗? PostMessage(WM_CLOSE)和调用EndDialog有什么区别?
【解决方案3】:

Serge - 不幸的是,您的回答不是最好的方法。 PostQuitMessage(0) 是要走的路,MFC 会为你销毁窗口。您应该避免直接调用 m_pMainWindow->DestroyWindow()。

【讨论】:

  • 文件没有说我不正确的地方。 DestroyWindow() 是一个虚函数,当您通过发布消息告诉它关闭窗口时,MFC 会为您调用它。最好让 MFC 为您执行此操作,而不是直接调用它,因为通常在销毁窗口时会发生一系列事件,而 MFC 会处理它。在某些情况下,如果我们知道自己在做什么,我们可以直接调用它。
  • 您在哪里看到调用 PostQuitMessage() 会关闭或破坏您的窗口?
  • 可以查看 PostQuiteMessage() 的文档。显然发布 WM_CLOSE 也可以。我的建议是向窗口发布消息以关闭而不是直接销毁它。一旦它是相同的过程,应用程序无论如何都会自行结束,但一些专家给了我-1!
  • 阅读问题的 OP 和标题。用户询问如何“退出应用程序”,但您专注于窗口。
猜你喜欢
  • 1970-01-01
  • 2016-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-26
  • 1970-01-01
相关资源
最近更新 更多