views:

686

answers:

3
// CMyDialog inherits from CDialog 
void CMyFrame::OnBnClickedCreate()
{
    CMyDialog* dlg = new CMyDialog();
    dlg->Create( IDD_MYDIALOG, m_thisFrame );
    dlg->ShowWindow( SW_SHOW );
}

I'm pretty sure this leaks. What I'm really asking is: is there any "magic" in MFC that does dialog cleanup when the dialog is destroyed. How would it work if dlg wasn't a pointer but declared on the stack - wouldn't the destructor destroy the window when dlg goes out of scope.

+3  A: 

Yes, that's a leak. And yes, the window would be destroyed if the object was stack-allocated. Using dialogs as stack-allocated objects is typical for modal dialogs - you call a method for showing a dialog as a modal window and that method only returns when the dialog is closed and the object is destroyed after that.

sharptooth
Thanks. I forgot to say this is for a Modeless dialog. I'm assuming in this case for cleanup the dialog object has to be a member variable - so it can be destroyed/de-allocated in the frames destructor.
Richard
+2  A: 

If you manually call Create on a dialog, you have to manually Destroy it as well.
When using DoModal() this isn't necessary.

From MSDN:

Use the CWnd::DestroyWindow function to destroy a dialog box created by the Create function.

fretje
+5  A: 

Yes, it is memory leak in your case but you can avoid memory leak in cases where modeless dialog allocated on the heap by making use of overriding PostNcDestroy.

Dialogs are not designed for auto-cleanup ( where as Main frame windows, View windows are). In case you want to provide the auto-cleanup for dialogs then you must override the PostNcDestroy member function in your derived class. To add auto-cleanup to your class, call your base class and then do a delete this. To remove auto-cleanup from your class, call CWnd::PostNcDestroy directly instead of the PostNcDestroy member in your direct base class.

void MyDialog::PostNcDestroy() 
{

    CDialog::PostNcDestroy();
    delete this;
}

How this works (from MSDN):

When destroying a Windows window, the last Windows message sent to the window is WM_NCDESTROY. The default CWnd handler for that message (CWnd::OnNcDestroy) will detach the HWND from the C++ object and call the virtual function PostNcDestroy. Some classes override this function to delete the C++ object.

"delete this" will free any C++ memory associated with the C++ object. Even though the default CWnd destructor calls DestroyWindow if m_hWnd is non-NULL, this does not lead to infinite recursion since the handle will be detached and NULL during the cleanup phase.

You can also refer MSDN (Destroying Window Objects ) for further details.

Note:

This works for modeless dialog that can be allocated on the heap.

aJ