【问题标题】:CDialog - EndDialog from a MODELESS dialog?CDialog - 来自MODELESS对话框的EndDialog?
【发布时间】:2013-04-27 20:42:13
【问题描述】:

MS documentation(和others)“清楚地”声明:

... 因为 CDialog 的普通 OnOk 和 OnCancel 成员函数 对象将调用 EndDialog,确保您的无模式对话框确实 不调用这些函数而是覆盖

由于CDialog::OnOk 有效地调用CDialog::EndDialog,该方法看起来像:

void CDialog::EndDialog(int nResult)
{
    ASSERT(::IsWindow(m_hWnd));

    if (m_nFlags & (WF_MODALLOOP|WF_CONTINUEMODAL))
        EndModalLoop(nResult);

    ::EndDialog(m_hWnd, nResult);
}

我们还可以检查the docs for ::EndDialog 再次“明确”状态:

由 DialogBox、DialogBoxParam 创建的对话框, DialogBoxIndirect 和 DialogBoxIndirectParam 函数必须是 使用 EndDialog 函数销毁。应用程序调用 EndDialog 从对话框过程中;不得使用该功能 用于任何其他目的。

然而,我有一个 CDialog 派生类,它的默认行为是 wrt。 OnOKand 似乎当我使用非模态/非模态时一切正常。

即: * 当我关闭(无模式)对话框时,它会关闭/从视图中移除。 * 应用程序没有显示任何内存泄漏。 (MFC 调试构建)

那又怎样?我是否需要阻止EndDialog 并自己致电DestroyWindow或不需要


注意:我知道文档和“网络”是怎么说的。只是我还没有找到为什么我需要做不同的事情,而且这个类应该可以用于无模式和模态模式,所以不必做任何不同的事情可能会很方便。 p>

【问题讨论】:

  • 我怀疑你正在泄漏一个窗口。这不会在您的应用程序中显示为内存泄漏,因为窗口是由系统维护的。检查任务管理器中的“用户对象”列,查看值是否随时间增长。

标签: winapi visual-c++ mfc modal-dialog modeless


【解决方案1】:

CDialog::OnOKMSDN Docs 明确指出

如果在无模式对话框中实现确定按钮,则必须 覆盖 OnOK 方法并在其中调用 DestroyWindow。不要打电话 基类方法,因为它调用 EndDialog 这使得 对话框不可见但不会破坏它

因此,您需要覆盖 CDialog::OnOK 并在内部调用 DestroyWindow() -- 这是来自 MSDN 的修改示例:

class CDlg : public CDialog
{
    ...
    BOOL m_bModal;
    ...
}

CDlg::CDlg(CWnd* pParent /*=NULL*/)
: CDialog(CDlg::IDD, pParent)
{
    ...
    m_bModal = FALSE;
    ...
}

INT_PTR CDlg::DoModal()
{   m_bModal = TRUE;
    const INT_PTR rval = CDialog::DoModal();
    m_bModal = FALSE;
    return rval;
}

void CDlg::OnOK() 
{ 
   if (!UpdateData(TRUE)) 
   {
      TRACE(_T("UpdateData failed during dialog termination\n"));
      // The UpdateData routine will set focus to correct item
      return;
   }
   if (m_bModal)
       EndDialog(IDOK);
   else
       DestroyWindow();
}

void CDlg::OnCancel()
{
   if (m_bModal)
       EndDialog(IDCANCEL);
   else
       DestroyWindow();
}

【讨论】:

  • 谢谢。我想我没有在这里检查方法文档。现在这似乎很清楚了。
  • @MartinBa 更新了上面的代码来处理模态和非模态对话框
  • 你确定这有效吗?在我原来的情况下,我逐步完成了CDialog::EndDialog 函数,我想我记得这些标志也被设置在我用Create 创建的无模式对话框中......虽然在这里没有代码来检查这个atm。
  • 抱歉,不——将启动一个示例项目并回复您
  • 无法尝试这个(我的 VisualStudio 有一些问题),但我查看了 MFC 源代码,看起来在两种情况下都设置了标志,似乎没有任何其他标志——最简单的解决方法似乎是拥有一个成员变量m_bModal并将其设置在DoModal上;如果你有很多这样的对话框,最好自己编写从 CDialog 派生的中间基类,并使用这个类作为所有对话框的基类
猜你喜欢
  • 1970-01-01
  • 2012-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-24
  • 2012-01-11
  • 2014-10-06
相关资源
最近更新 更多