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

MFC dialog based application fails to invoke dialog twice

本文关键字:对话框 两次 调用 MFC 应用程序 基于      更新时间:2023-10-16

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

即使不更改模板,问题也保持不变。GetLastError(( 返回 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(( 失败返回 -1。

来自m_pMainWnd的文档

Microsoft基础类库将自动终止 关闭 m_pMainWnd 引用的窗口时的线程。如果 此线程是应用程序(应用程序(的主线程 也将被终止。如果此数据成员为 NULL,则主窗口 对于应用程序的 CWinApp 对象,将用于确定何时 终止线程。m_pMainWnd 是 CWnd* 类型的公共变量。

因此,当主窗口关闭时,MFC 已经决定应用程序已结束,不会创建其他窗口。

最少的可重现代码:

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 linen");
return FALSE;
}

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

更好的是,更改程序设计,以便始终有一个用于 GUI 线程的主窗口。