CDialog - EndDialog from a MODELESS dialog?
mfc, modal-dialog, modeless, visual-c++, winapi
Solution
The MSDN Docs for `CDialog::OnOK` clearly states
If you implement the OK button in a modeless dialog box, you must override the OnOK method and call DestroyWindow inside it. Do not call the base-class method, because it calls EndDialog which makes the dialog box invisible but does not destroy it
So you would need to override `CDialog::OnOK` and call `DestroyWindow()` inside -- here's a modified example from 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();
}
Problem
The MS documentation (and others) "clearly" states: ... Because the normal OnOk and OnCancel member functions of a CDialog object would call EndDialog, make sure your modeless dialog box does not call those functions and instead overrides Since `CDialog::OnOk` effectively calls `CDialog::EndDialog`, and that method looks like: ``` void CDialog::EndDialog(int nResult) { ASSERT(::IsWindow(m_hWnd)); if (m_nFlags & (WF_MODALLOOP|WF_CONTINUEMODAL)) EndModalLoop(nResult); ::EndDialog(m_hWnd, nResult); } ``` we can also check the docs for `::EndDialog` which again "clearly" state: Dialog boxes created by the DialogBox, DialogBoxParam, DialogBoxIndirect, and DialogBoxIndirectParam functions must be destroyed using the EndDialog function. An application calls EndDialog from within the dialog box procedure; the function must not be used for any other purpose. Yet, I have a `CDialog` derived class that has it's default behavior wrt. `OnOK`and seemingly everything is working when I use it non-modal / modeless. That is: * When I close the (modeless) dialog, it is closed/removed from view. * The application doesn't show any memory leaks. (MFC debug build) So what? Do I need to prevent `EndDialog` and call `DestroyWindow` myself or not? Note: I know what the docs and "the web" says. It's just that I haven't yet found why I need to do it differently, and this one class should be usable for modeless and modal mode, so not having to do anything different might be handy.