CDialog - 来自MODELESS对话框的EndDialog?

时间:2013-05-03 12:31:43

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

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。当我使用非模态/无模式时,OnOK看似一切正常。

那是: *当我关闭(无模式)对话框时,它将被关闭/从视图中删除。 *该应用程序不显示任何内存泄漏。 (MFC调试版本)

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


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

1 个答案:

答案 0 :(得分:3)

CDialog::OnOK的{​​{3}}明确说明

  

如果在无模式对话框中实现“确定”按钮,则必须执行此操作   覆盖OnOK方法并在其中调用DestroyWindow。不要打电话   基类方法,因为它调用EndDialog来生成   对话框不可见但不会破坏它

所以你需要覆盖CDialog::OnOK并在里面调用DestroyWindow() - 这是MSDN Docs的修改示例:

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