Winapi CDialog-从无模式对话框中结束对话框?

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和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);
}
我们还可以再次检查“清楚”状态:

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

然而,我有一个
CDialog
派生类,它有它的默认行为wrt
OnOK
而且当我使用非模态/非模态时,似乎一切都在工作

即: *当我关闭(无模式)对话框时,它将关闭/从视图中删除。 *应用程序没有显示任何内存泄漏。(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();
}