基于 MFC 对话框的应用程序无法调用对话框两次

MFC dialog based application fails to invoke dialog twice

我有一个基于 MFC 对话框的应用程序,我想在其中更改对话框。为此,我关闭对话框并尝试使用另一个对话框模板再次加载它。对话框的第二次调用失败,return 代码为 -1。

即使不更改模板,问题仍然存在。 GetLastError() returns 0。我使用 AppWizard 生成了最简单的示例。

应用程序向导在 CMyApp::InitInstance 中生成以下代码:

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

这个我改成了:

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)

...

第一个 DoModal() 工作正常。当我按确定或取消时,第二个 DoModal() 失败 returning -1.

来自 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*.

所以当main window 关闭时,MFC 已经决定应用程序结束,additional windows 将不会创建。

最小可重现代码:

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;
}

要修复它,您可以删除行 //m_pMainWnd = pdlg; 并让 MFC 处理它。

更好的是,更改程序设计,使 GUI 线程始终有一个主window。