如果您只想显示错误信息,可能可以使用
AfxMessageBox()
而不是创建自己的对话框。请参见
Microsoft Developer Network - AfxMessageBox。
如果要创建自己的对话框框架,通常需要:
- 使用资源编辑器创建对话框模板
- 使用类向导创建封装对话框的类,并实现所需的行为
- 将代码插入到适当的位置以创建和显示对话框
但是,对于不需要复杂行为支持类的简单对话框,可以跳过使用类向导创建封装类的步骤,直接使用
CDialog
。
需要回答的一个问题是对话框的生存期以及它是模态还是非模态的。模态对话框要求用户执行某些操作才能继续进行应用程序处理。而非模态对话框则不会像模态对话框一样阻止应用程序运行。此外,还有系统模态对话框样式。
既然您说它将是一个模态对话框,那么其生命周期将很短,因此整个构建、显示和销毁过程可能会在一系列代码行中完成。例如,在具有命令处理程序的 CView
类中显示模态对话框框,您可能会有以下代码:
void CViewThing::OnCommandMenuItem ()
{
CDialog BadFileD(IDD_STATUS);
int iRetStatus = BadFileD.DoModal();
}
上述代码使用对话框资源模板
IDD_STATUS
创建了一个对话框,并将其显示为模态对话框。由于它是局部对象,当变量
BadFileD
超出范围时,对话框析构函数将被触发并为您清理资源。
您还可以拥有一个非模态对话框。在非模态对话框的情况下,您需要考虑变量生命周期,因为一旦变量超出范围,析构函数将被触发,对话框将消失。
因此,对于与某个视图类一起使用的非模态对话框(例如提供某种工具箱),
CDialog
变量将是使用它的
CView
类的成员。创建非模态对话框后,可以使用
CDialog
类的
ShowWindow()
成员函数(实际上是从中派生
CDialog
的
CWnd
类的成员函数)来显示或隐藏它。
void CViewThing::OnCommandMenuItem ()
{
BadFileD.Create(IDD_STATUS, this);
BadFileD.ShowWindow(SW_SHOW);
}
在
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)
CDialog BadFileD;
而不是CDialog *BadFileD = new CDialog();
。这样更简单,并且你不必担心在完成后删除指针。请注意,两者之间的区别在于一个是实例化 CDialog 对象,而另一个是动态地分配并实例化 CDialog 指针。 - Mark Ransom