3

MS 文档(和其他文档)“清楚”指出:

... 因为 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);
}

我们还可以检查再次“明确”声明的文档:::EndDialog

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

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

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

所以呢?我是否需要预防EndDialog打电话给DestroyWindow自己?


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

4

1 回答 1

3

MSDN Docs明确说明CDialog::OnOK

如果在无模式对话框中实现 OK 按钮,则必须重写 OnOK 方法并在其中调用 DestroyWindow。不要调用基类方法,因为它调用 EndDialog 使对话框不可见但不会破坏它

因此,您需要覆盖CDialog::OnOK并在内部调用- 这是MSDNDestroyWindow()的一个修改示例:

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();
}
于 2013-05-04T08:21:40.887 回答