Reputation: 43
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.
Upvotes: 1
Views: 472
Reputation: 31599
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.
Upvotes: 4