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
,当我以非模态/非模态方式使用它时,似乎一切正常。那是:
*当我关闭(无模式)对话框时,它是关闭的/从 View 中删除的。
*该应用程序不显示任何内存泄漏。 (MFC调试版本)
所以呢?是否需要阻止
EndDialog
并自己调用DestroyWindow
?注意:我知道文档和“网络”怎么说。只是我还没有找到为什么我需要做不同的事情,而这一类应该可用于无模式和模态模式,因此不必做任何不同的事情可能会很方便。
最佳答案
CDialog::OnOK
的MSDN 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();
}