MFC DoModal对话

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MFC DoModal对话相关的知识,希望对你有一定的参考价值。

好的,所以我承认我不了解Windows API甚至MFC。

当事情变得毛茸茸(文件名字符串中的非法字符)时,我会弹出一个错误窗口,我希望错误框是模态的。

对于我的生活,我无法弄清楚它为什么在击中doModal时崩溃。

这是我认为可以修复的代码。此代码位于主窗口中按钮的事件处理程序中。

CDialog *BadFileD = new CDialog();
BadFileD->Create(IDD_STATUS, this); 
BadFileD->DoModal();

我只是处于临界状态吗?

答案

对于显示模式对话框,您应该仅使用DoModal方法

CDialog *BadFileD = new CDialog(IDD_STATUS, this);
BadFileD->DoModal();

你可以阅读article的评论

另一答案

MFC对话框分为两个模式,模态对话框和无模式对话框。

(1)模态对话框用法:

CDialog dlg;
dlg.DoModal();

(2)无模式对话框用法:

CMyDialog *pDlg = new CMyDialog();
pDlg->Create(ID_DLG, this);
pDlg->ShowWindows(SW_SHOW);

如您所见,我们需要新的指针,但不能删除它。因此,您需要在我们的CMyDialg类中执行以下操作:

  1. 在qazxsw poi和qazxsw poi中添加qazxsw poi方法。
  2. DestroyWindow()方法中添加“OnOk()”。

如果不这样做,您的代码可能会导致内存泄漏。 OnCancel()是一个类成员,你在析构函数中删除。我建议使用无模式对话框。

另一答案

如果您只想显示错误消息,可能只是使用delete this;而不是创建自己的对话框。见PostNcDestroy()

如果您想通常使用MFC项目来创建自己的对话框,通常情况下:

  • 使用资源编辑器创建对话框模板
  • 使用实现所需行为的类向导创建一个封装对话框的类
  • 插入代码以创建对话框并将其显示到适当的位置

但是,如果使用一个简单的对话框,不需要复杂行为的支持类,则可以跳过使用类向导创建封装类的步骤,并直接使用BadFileD

需要回答的一个问题是对话的生命周期以及它是模态的还是无模式的。模式对话框要求用户为应用程序执行某些操作以继续通过模式对话框。无模式对话框不会像模式对话框那样阻止应用程序。还有一个系统模式对话框样式。

既然你说它将是一个模态对话框,那么生命周期将很短,因此整个构造,显示和销毁可能会在一系列代码行中。例如,在AfxMessageBox()类中,命令处理程序显示模式对话框,您可能具有:

Microsoft Developer Network - AfxMessageBox

以上是使用对话框资源模板CDialog创建一个对话框,并将其显示为模式对话框。由于它是本地对象,当变量CView超出范围时,将触发对话框析构函数并为您清理资源。

您还可以使用无模式对话框。对于无模式对话框,您需要考虑变量生命周期,因为只要变量超出范围,析构函数就会触发,对话框将消失。

因此,对于与某些视图类一起使用的无模式对话框,可能提供某种类型的工具箱,void CViewThing::OnCommandMenuItem () { CDialog BadFileD(IDD_STATUS); int iRetStatus = BadFileD.DoModal(); // check for status such as IDOK, etc. // do whatever is necessary. } 变量将是使用它的IDD_STATUS类的成员。在创建无模式对话框之后,通过使用BadFileD类的CDialog成员函数(实际上是CView派生的ShowWindow()类的成员)显示或不显示它。

CDialog

CWnd类中,你将有一个成员变量CDialog

其他考虑因素

在上面的所有示例中,我们都没有使用指针,因此当void CViewThing::OnCommandMenuItem () { BadFileD.Create(IDD_STATUS, this); BadFileD.ShowWindow(SW_SHOW); // display the dialog } 变量超出范围时,无论是退出成员函数还是使用对话框的对象被销毁,那么对话框也是如此。这个对象管理是为我们完成的。

使用无模式对话框时必须考虑的一件事是如何在不再需要它时将其销毁。

由于模态对话框通常是一个短期对象,通常作为堆栈上的局部变量创建,因此通常只是让它超出范围来处理与破坏有关的所有事情。

但是,无模式对话框的生命周期要求使用CViewThing方法在不再需要时销毁对话框。见CDialog BadFileD;

第三种使用场景 - 嵌入对话框

对话框的第三种用法有时会派上用场,将对话框作为控件嵌入到另一个窗口中。

在上面的示例中,对话框模板为对话框指定CDialog样式,该对话框是对话框的标准样式,因为使用对话框的常规方式是显示为单独的窗口。

但是,如果将DestroyWindow()样式更改为Microsoft Developer Network - Destroying the Dialog Box,则可以将对话框作为控件嵌入到另一个窗口中。您可以删除其他样式设置,如WS_POPUPWS_POPUPWS_CHILD,并从对话框模板中删除WS_SYSMENU行以进一步更改对话框。所以你最终会得到类似的东西:

DS_MODALFRAME

然后使用生成的对话框,类似于使用WS_CAPTION的无模式对话框。

如果需要在其容器窗口中重新定位嵌入式对话框,可以使用CAPTION方法执行此操作。例如,以下内容将在其包含窗口内移动对话框窗口,使其距离左侧20像素,距离包含窗口顶部10个像素。

IDD_STATUS DIALOGEX 0, 0, 435, 266
STYLE DS_SETFONT | WS_CHILD
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    LTEXT           "this is some static text to display on this dialog.",IDC_STATIC,81,63,200,32
END

以上是关于MFC DoModal对话的主要内容,如果未能解决你的问题,请参考以下文章

在 DoModal 之后隐藏 MFC 对话框时,它的控件是不是被破坏?

在启动前隐藏一个MFC DoModal对话框

MFC(C++)CDialog DoModal()没有按预期工作

从 CDialog 派生的对话框在 DoModal (MFC/C++) 之后返回 -1

如何初始化模态对话框? (C++/MFC)

MFC Domodal 返回-1的一种情况