Winapi CDialog-从无模式对话框中结束对话框?
(和)“明确”规定: 。。。因为CDialog的正常OnOk和OnCancel成员函数 对象将调用EndDialog,请确保您的无模式对话框 不调用这些函数,而是重写 由于Winapi CDialog-从无模式对话框中结束对话框?,winapi,visual-c++,mfc,modal-dialog,modeless,Winapi,Visual C++,Mfc,Modal Dialog,Modeless,(和)“明确”规定: 。。。因为CDialog的正常OnOk和OnCancel成员函数 对象将调用EndDialog,请确保您的无模式对话框 不调用这些函数,而是重写 由于CDialog::OnOk有效地调用了CDialog::EndDialog,该方法如下所示: void CDialog::EndDialog(int nResult) { ASSERT(::IsWindow(m_hWnd)); if (m_nFlags & (WF_MODALLOOP|WF_CONTI
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);
}
我们还可以再次检查“清楚”状态:
由对话框、DialogBoxParam、,
DialogBoxIndirect和DialogBoxIndirectParam函数必须是
使用EndDialog函数销毁。应用程序调用EndDialog
从对话框程序中;不得使用该功能
为了任何其他目的
然而,我有一个CDialog
派生类,它有它的默认行为wrtOnOK
而且当我使用非模态/非模态时,似乎一切都在工作
即:
*当我关闭(无模式)对话框时,它将关闭/从视图中删除。
*应用程序没有显示任何内存泄漏。(MFC调试生成)
那又怎样?我是否需要阻止EndDialog
并自己调用destronWindow
注:我知道文档和“网络”是怎么说的。只是我还没有找到为什么我需要做不同的事情,这个类应该可以用于无模式和模式模式,所以不需要做任何不同的事情可能会很方便。for
CDialog::OnOK
清楚地说明
如果在无模式对话框中实现“确定”按钮,则必须
重写OnOK方法并在其中调用DestroyWindow。不要打电话
基类方法,因为它调用EndDialog使
对话框不可见,但不会破坏它
因此,您需要重写CDialog::OnOK
并在内部调用destronWindow()
——下面是一个修改后的示例:
我怀疑你把窗户漏了。这不会在应用程序中显示为内存泄漏,因为windows由系统维护。检查任务管理器中的“用户对象”列,查看值是否随时间增长。谢谢。我想我没有检查这里的方法文档。这看起来很清楚了。@MartinBa更新了上面的代码来处理模态和非模态对话框。你确定这有效吗?在我最初的例子中,我使用了
CDialog::EndDialog
函数,我想我还记得在使用Create
创建的无模式对话框中设置了这些标志。。。这里没有检查这个atm的代码。抱歉,没有--将启动一个示例项目并返回到您无法尝试这个(我的VisualStudio有一些问题),但我查看了MFC源代码,看起来两种情况下都设置了标志,似乎也没有任何其他标志——最简单的修复方法似乎是使用成员变量m_bModal
并将其设置为DoModal;如果您有很多这样的对话框,那么最好从CDialog派生出自己的中间基类,并将该类用作所有对话框的基类
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();
}