好的,所以我承认我不了解Windows API甚至MFC。
当事情变得毛茸茸(文件名字符串中的非法字符)时,我会弹出一个错误窗口,并且我希望错误框是模态的。
对于我的生活,我无法弄清楚为什么它会在击中doModal时崩溃。
以下是我认为可以修复的代码。此代码位于主窗口中按钮的事件处理程序中。
CDialog *BadFileD = new CDialog();
BadFileD->Create(IDD_STATUS, this);
BadFileD->DoModal();
我只是处于临界状态?
答案 0 :(得分:19)
MFC对话框分为两个模式,模态对话框和无模式对话框。
(1)模态对话框用法:
CDialog dlg;
dlg.DoModal();
(2)无模式对话框使用:
CMyDialog *pDlg = new CMyDialog();
pDlg->Create(ID_DLG, this);
pDlg->ShowWindows(SW_SHOW);
如您所见,我们需要新的指针,但不能删除它。因此,您需要在我们的CMyDialg
课程中执行以下操作:
DestroyWindow()
和OnOk()
和<{li>中添加OnCancel()
。{/ li>
delete this;
方法中添加“PostNcDestroy()
”。如果不这样做,您的代码可能会导致内存泄漏。 BadFileD
是类成员,您在析构函数中删除。我建议使用无模式对话框。
答案 1 :(得分:7)
对于显示模式对话框,您应该只使用DoModal方法
CDialog *BadFileD = new CDialog(IDD_STATUS, this);
BadFileD->DoModal();
您可以阅读article
的评论答案 2 :(得分:1)
如果您只想显示错误消息,则可能只是使用AfxMessageBox()
而不是创建自己的对话框。参见Microsoft Developer Network - AfxMessageBox。
如果通常要使用MFC项目创建自己的对话框,则通常:
但是,通过一个简单的对话框,该对话框不需要用于复杂行为的支持类,您可以跳过使用类向导创建封装类的步骤,而直接使用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_POPUP
样式,这是对话框的标准样式,因为使用对话框的通常方式是显示为单独的窗口。
但是,如果将WS_POPUP
样式更改为WS_CHILD
,则可以将对话框作为控件嵌入到另一个窗口中。您可以删除其他样式设置,例如WS_SYSMENU
,DS_MODALFRAME
和WS_CAPTION
,并从对话框模板中删除CAPTION
行,以进一步更改对话框。所以您最终会得到类似的东西:
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
然后只使用生成的对话框,就像使用ShowWindow()
创建无模式对话框一样。
如果需要在容器对话框中重新定位嵌入式对话框,则可以使用SetWindowPos()
方法。例如,以下操作会将对话框窗口从其包含的窗口中移到包含窗口的左侧20像素和顶部10像素的位置。
BadFileD.SetWindowPos(NULL, 20, 10, 0, 0, SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER)