Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I detect if a modeless CDialog has been closed?

I have followed this question to make a non-modal/modeless dialog: How to display a non-modal CDialog?

I'm using MFC/C++ in VS2008. I'm more fluent with C# and .net than with MFC and C++.

I have a menu item in my form that launches the dialog. There can only be one instance of the dialog opened. The dialog displays fine. I can close it by clicking the X in the corner and it closes when I close the main form. The problem I am having is the dialog cannot be opened again after I click the X to close the dialog. I know it is because the pointer is never set back to NULL.

I have this in my form's header file:

CChildDialog *m_pDialog;

I have this part in my form's constructor:

m_pDialog = NULL;

When clicking on a menu item I have this code in the menu item's method (I modified it from the other SO answer because I only want one instance of the dialog opened):

if(m_pDialog == NULL)
{
    // Invoking the Dialog
    m_pDialog = new CChildDialog();
    BOOL ret = m_pDialog->Create(IDD_CHILDDIALOG, this);

    if (!ret)   //Create failed.
    {
        AfxMessageBox(_T("Error creating Dialog"));
    }    

    m_pDialog->ShowWindow(SW_SHOW);
}

Now I know I need to execute this part and set the pointer to NULL, but I don't know where to put this:

// Delete the dialog once done
delete m_pDialog;
m_pDialog = NULL;

Do I need to keep monitoring if the dialog has been disposed? Is there an event triggered to the parent form when the dialog is closed?

like image 740
Alex Avatar asked Feb 20 '23 14:02

Alex


2 Answers

If you want to recycle the contents of the window after closing it with X, you have to handle the WM_CLOSE message in your dialog:

void CChildDialog::OnClose()
{
    ShowWindow(SW_HIDE);
}

Then in the code that opens the window:

if(m_pDialog == NULL)
{
    // Invoking the Dialog
    m_pDialog = new CChildDialog();
    BOOL ret = m_pDialog->Create(IDD_CHILDDIALOG, this);

    if (!ret)   //Create failed.
    {
        AfxMessageBox(_T("Error creating Dialog"));
    }    
}

m_pDialog->ShowWindow(SW_SHOW); //moved outside the if(m_pDialog == NULL)

Hope it can help

like image 86
Albertino80 Avatar answered Mar 03 '23 00:03

Albertino80


If you want to delete the modeless dialog, then just do so.

If you want to delete the dialog's object when the user closed the modeless dialog you might take a look at WM_PARENTNOTIFY. If a child window is destroyed and the child windows has not the extended window style WS_EX_NOPARENTNOTIFY set, then windows sends a WM_PARENTNOTIFY with wParam=WM_DESTROY to the parent window. You should implement a handler for that message in the parent window and check if it's the modeless dialog that is being destroyed.

like image 38
Werner Henze Avatar answered Mar 02 '23 23:03

Werner Henze