简体   繁体   中英

MFC dialog based application fails to invoke dialog twice

I have an MFC dialog based application where I want to change the dialog. To do this I close the dialog and try to load it again with another dialog template. The second invocation of the dialog fails with a return code of -1.

Even without changing the template, the problem stays the same. GetLastError() returns 0. I have used AppWizard to generate the simplest possible example.

The App wizard generates the following code in CMyApp::InitInstance:

CMyAppDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
    ...

This I changed to:

CMyAppDlg *pdlg = new CMyAppDlg;
m_pMainWnd = pdlg;
INT_PTR nResponse = pdlg->DoModal();
if (nResponse == IDOK)
{}
delete pdlg;

CMyAppDlg dlg1;
m_pMainWnd = &dlg1; // leaving this out makes no difference
nResponse = dlg1.DoModal();// this exits immediately with a -1
if (nResponse == IDOK)

...

The first DoModal() works fine. When I press OK or Cancel, the second DoModal() fails returning -1.

From documentation for m_pMainWnd

The Microsoft Foundation Class Library will automatically terminate your thread when the window referred to by m_pMainWnd is closed. If this thread is the primary thread for an application, the application will also be terminated. If this data member is NULL, the main window for the application's CWinApp object will be used to determine when to terminate the thread. m_pMainWnd is a public variable of type CWnd*.

So by the time the main window is close, MFC has already decided that the application is over, additional windows will not be created.

Minimum reproducible code:

BOOL CMyWinApp::InitInstance()
{
    CWinApp::InitInstance();

    CDialog *pdlg = new CDialog(IDD_DIALOG1);
    m_pMainWnd = pdlg; //<- remove this to see the message box
    pdlg->DoModal();
    m_pMainWnd = NULL; //<- this line has no effect basically
    delete pdlg;

    MessageBox(0, L"You won't see this message box", 0, 0);
    TRACE("but you will see this debug line\n");

    return FALSE;
}

To fix it, you can remove the line //m_pMainWnd = pdlg; and let MFC handle it.

Better yet, change the program design so that there is always one main window for the GUI thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM