VC++6.0入门【第六章 创建和使用对话框】
- 格式:doc
- 大小:6.33 MB
- 文档页数:34
第6章创建和使用对话框
对话框是一种用户界面,几乎每一个Windows程序都使用对话框与用户进行交互。
对话框可能是一个简单的只含有OK按钮的消息框,也可以是一个复杂的数据输入表单。
对话框上有一些方便用户输入的控件,对话框依靠这些控件与用户进行交互,其实质是一个接收消息的窗口。
在本章节我们主要讲述模式对话框和无模式对话框的原理和使用方法,下一章将详细介绍各种控件的使用。
你将学习创建一个对话框,使用对话框模板编辑一个对话框资源,并在程序中调用对话框的方法。
6.1 对话框的基本原理
6.1.1 对话框的工作原理
在创建一个对话框之前,我们先来了解一下对话框是如何工作的,对话框的数据来自三方面:对话框资源、对话框对象、和一个文档对象:
1.对话框资源
对话框资源是一个用户输入或取得数据的图形界面。
这个图形界面是使用Develop Studio的对话框编辑器在对话框模板上创建的,程序员可以在对话框模板上增加并编辑控件,生成对话框资源。
当应用程序运行时,就可以得到一个对话框。
2.对话框对象
MFC使用CDialog类来描述对话框,它是CWnd类的派生类。
在CWnd类的基础上增加了数据交换的功能。
当创建一个新的对话框资源后,使用ClassWizard可以创建一个对话框类的派生类。
对话框对象实现了对话框和应用程序之间的通信。
在应用程序中定义一个对话框对象后,在对话框显示前,可以通过访问对话框对象的成员变量为一个对话框的控件初始化,在对话框关闭后,可以通过访问对话框对象的成员变量获得用户的输入数据。
3.文档对象
MFC使用文档对象描述应用程序处理的数据,用户输入的数据要进一步的处理,通常要先存贮到文档对象中。
例如:一个学生记录处理的应用程序,用户通过一个对话框输入学生记录并贮存到一个文件中。
应用程序的处理顺序是:用户在对话框中输入信息,通过对话框对象得到输入信息,将输入信息整理到文档对象中,使用序列化函数将文档对象存贮到一个文件中,所以文档对象扮演了一个很重要的数据交换的角色。
MFC使用以上三者实现用户与应用程序之间数据交换,数据交换流程见图6-1所示,遵循四个步骤。
图6-1 对话框基本原理
6.1.2 对话框的类型
对话框分为模式对话框和无模式对话框两种。
当一个模式对话框打开了,在其关闭之前,用户不能转向其它用户界面对象,只能与该对话框进行交互。
我们平时接触到的对话框,大多数都是模式对话框,例如,一个执行菜单命令File->Save 后,Save 对话框被打开后,用户不能再做其它工作,只能保存完文件或取消保存文件,关闭对话框窗口后,才能做其它工作。
无模式对话框恰恰相反,当用户打开一个无模式对话框,对话框停留在屏幕上,仍然允许用户与其它用户界面对象进行交互。
无模式对话框最典型的例子是在Word 中使用的查找与替换对话框,打开该对话框后,可以交替地进行文档编辑,和查找替换操作。
从第一节的介绍可以看到对话框的设计任务主要包括对话框资源模板的设计,对话框类的设计和对话框的运行,绝大多数对话框的创建任务,模式对话框和无模式对话框都是相同的,只有在对话框与应用程序代码的交互中,也就是对话框的运行中,两者有明显的区别。
6.2设计对话框资源
6.2.1创建对话框
使用AppWizard 生成的单文档或多文档应用程序,只有一个默认的About 对话框,用于显示应用程序版本信息。
需要使用对话框模板创建自己的对话框资源。
Develop Studio 提供的对话框模板创建了一个基本界面,包括一个OK (确定)按钮和一个Cancel (取消)按钮等。
你可以移动、修改、删除这些控件,或者是增加新的控件到对话框模板,构成应用程序所需的对话框资源。
创建一个对话框资源到工程的步骤:
(1) 使用AppWizard 生成一个单文档的MFC 应用程序Exam6_1。
(2) 选择Insert->Resource 菜单命令。
(3) 在弹出的Insert Resource 对话框左边的列表中选择Dialog ,单击New 按钮。
Public:
data
member
document xxxxxxx xxxxxxx xxxxxxx xxxxxxx 创建对话框模板 1 数据交换和验证 2 定义对话框类和 3公有成员变量
运行对话框,修改 4 文档对象
(4) 在项目工作区中选择ResourceView 面板,展开Dialog 文件夹,可以看到增加了一个对话框资源
IDD_DIALOG1,如图6-2所示,双击IDD_DIALOG1,在编辑区出现一个对话框模板。
图6-2 Exam6_1对话框设计_新建对话框资源
6.2.2增加控件
一个控件是能够放置在一个对话框中,提供应用程序与用户交互的某种功能。
例如,Edit Box 提供用户文本输入的场所,一组Radio Button 提供用户对某一主题的单项选择。
MFC 将控件设计为对话框窗口的子窗口,控件通过事件通知消息与父窗口联系。
在一个对话框资源中增加控件的操作十分方便,只需从图6-2所示的控件工具栏中选中要增加的控件,再将此控件拖拉至对话框模板中的确定位置上,松开鼠标按键即生成一个控件。
调整控件的位置和大小的操作与Word 中对文本框的操作完全一样。
在默认情况下,控件工具栏总是打开的,如果没有打开,可以在Develop Studio 工具栏后的空白处,单击鼠标右键,在弹出的快捷菜单中选择Controls ,便可打开控件工具栏。
图6-3中列出了VC ++6.0中支持的标准控件名称,我们可以很方便地从控件工具栏中生成新的控件,但每一种控件都具有不同的特性,需要学习和掌握。
对话框模板
对话框资源ID
控件工具栏
Check Box Group Box Picture Edit Control Vertical Scroll Bar Progress Hot Key Combo Box Radio Button Button List Box Slider Selection Tool Static Text Horizontal Scroll Bar Spin
图6-3 标准控件
下面我们试着设计一个可以输入5门功课成绩的输入窗口,在上一节生成的对话框资源IDD_DIALOG1中做以下操作,得到如图6-4所示的对话框:
(1)调整对话框模板窗口大小,将OK和Cancel按钮移到窗口的底部。
(2)控件工具栏中选中Static Text(静态文本)控件,拖到对话框模板中。
(3)通过复制和粘贴操作,生成其它四个Static Text控件。
(4)控件工具栏中选中Edit Box控件(编辑框),拖到对话框模板中。
(5)通过复制和粘贴操作,生成其它四个Edit Box控件
图6-4 EX6对话框设计_增加控件
6.2.3设置控件属性
一个控件相关的属性设置决定了一个控件可操作行为和显示。
例如,控件的ID是控件的一个重要属性,MFC内部是以控件ID来标识一个控件,当消息产生后,是哪一个控件需要进行处理,MFC 内部使用的是控件ID。
属性的设置是在与每个控件相对应的属性对话框中进行的,单击鼠标右键,在弹出的快捷菜单中选择Properties,打开属性对话框。
每一种控件的属性对话框都有所不同,与其特性相关,在下一章我们将详细介绍一些常用控件的属性含义。
对上一节的对话框IDD_DIALOG1中的控件作属性设置:
(1)鼠标选中第一个Static Text对象,单击鼠标右键,在弹出的快捷菜单中选择Properties,弹出属
性对话框,如图6-5所示。
图6-5 属性对话框设置
(2)修改Caption右边的文本框,输入“高等数学”,单击关闭按钮,关闭属性对话框。
(3)重复步骤(1)(2),将其它四个Static控件的Caption改为“大学物理”,“大学英语”,“哲学”和
“计算机基础”。
(4)同样的操作打开5 个Edit Box控件的属性对话框,修改ID为IDC_SCORE1、IDC_SCORE2、
IDC_SCORE3、IDC_SCORE4、IDC_SCORE5。
(5)打开按钮OK的属性对话框,修改Caption为“确定”。
(6)打开按钮Cancel的属性对话框,修改Caption为“取消”。
操作完毕,对话框如图6-6所示。
图6-6 EX6对话框设计_设置属性
同样,对话框的属性设计也是在对话框的属性对话框中设置,在对话框任意空白处单击鼠标右键,在弹出的快捷菜单中选择Properties,如图6-7所示。
在Caption中填写“成绩录入”,将成为对话框的标题,单击Font会弹出字体对话框,能设置对话框中显示的字体格式。
其它的几个标签页还提供了选项,可以修改对话框窗口的显示样式,可以自己试一试。
图6-7 对话框属性设置
6.2.4组织和安排控件
当选择了一个对话框资源进入对话框编辑器时,Develop Studio的菜单栏上会增加一个菜单Layout,如图6-8所示。
Layout 菜单提供了在对话框模板中合理布置控件的功能菜单项。
Align提供了控件的六种对齐方式:左对齐、右对齐、上对齐、下
对齐、水平居中、垂直居中。
Space Evenly提供了两种等间距方式:垂直方向等间距、水平方
向等间距。
Make Same Size提供了三种等尺寸方式:宽相等、高相等、两者
都相等。
Arrange Button提供了两种组织按键的方式:底部排列、右边排
列。
Center in Dialog提供了两种居中方式:水平居中、垂直居中。
Flip用于水平反方向显示控件及窗口标题。
Size to Content命令根据内容决定控件的大小,例如,按钮的大小
由按钮上的显示文本决定。
图6-8 Layout下拉菜单
通过上面几个菜单项的操作能够很方便地齐整控件的摆放位置。
现在我们可以整理一下IDD_DIALOG1中摆放凌乱的控件:
(1)确定第一个和最后一个Static Text控件的位置,同时选中5个Static Text控件,执行菜单命令
Layout->Make Same Size-width
(2)执行菜单命令Layout->Align-Bottom,水平对齐5个控件。
(3)执行菜单命令Layout->Space Evenly-Across,使5个控件水平等间距。
(4)选择“哲学”,执行菜单命令Layout->Size to Content,微调控件位置
(5)确定第一个和最后一个Static Text控件的位置,同时选中5个Static Text控件,执行菜单命令
Layout->Align->Bottom和Layout->Space Evenly->Across。
操作完毕,可以看到控件整齐地排放在对话框模板上,如图6-9所示。
图6-9 EX6对话框设计_整理控件
在Windows环境中通常提供两种操作方法,鼠标操作方式和键盘操作方式,使用鼠标可以直接点击控件进行访问,使用键盘访问控件需要通过Tab键顺次找到某个控件。
Tab Order规定了使用Tab键访问
控件的顺序,一般Tab Order是控件生成的顺序,执行菜单命令Layout->Tab Order可以显示并修改Tab Order,对IDD_DIALOG1执行菜单命令Tab Order 如图6-10所示。
图6-10 显示Tab Order
改变Tab Order的方法既简单又直观,执行了Tab Order命令出现了顺序号之后,按你所想要的访问顺序依次点击每一个控件,完成后,点击空白处就可以了。
读者可以试练习将上图的Tab顺序变成先访问第一个Edit Box,访问完所有的Edit Box后再访问Button。
6.2.5测试对话框
当构造好一个对话框后,还不能立即在应用程序中运行对话框,MFC提供了Test命令,使程序员在设计阶段就能够测试对话框的运行效果。
测试对话框的方法有:
(1)菜单命令Layout->Test
(2)Dialog工具栏上的Test按钮
(3)快捷键Ctrl+T
测试对话框IDD_DIALOG1,试着使用文本框输入,并使用Tab键是否符合要求。
如图6-11所示。
测试对话框窗口
图6-11 Exam6_1对话框设计_测试对话框
6.3设计对话框类
一个对话框资源要加入到一个窗口应用程序中,首先要为它创建一个对话框类,是CDialog类的派生类。
应用程序运行时,窗口操作系统使用对话框类为对话框在内存开辟空间。
在Win32 API类型的窗口应用程序中,都是直接通过控件ID来访问对话框上的控件的,而MFC提供了连接变量来标识控件,连接变量是对话框的成员变量,同时对话框类有一套交换和验证数据的方式。
6.3.1 创建对话框类
创建对话框类的步骤如下:
1.保存已创建好的对话框模板。
2.确保新的对话框资源在对话框编辑器中打开状态下,打开ClassWizard窗口。
打开ClassWizard的方式有3种:
(1)窗口菜单命令View->ClassWizard
(2)快捷菜单命令ClassWizard
(3)快捷键:Ctrl+w
3.在弹出的Adding a Class对话框中,如图6-12所示,选择Create a new class单选钮,单击OK按钮。
图6-12 “增加类”对话框
4.在随后弹出的New Class对话框中,如图6-13所示,只需填写类的名称:CScoreDlg,单击OK按钮。
关闭ClassWizard,对话框类的创建就完成了。
填写类名
图6-13 填写新类名称
在Workspace窗口的ClassView面板中,可以看到增加了一个新的类CScoreDlg,选择FileView面板,在Header Files和Source Files文件夹中,可以看到该类的头文件和实现文件,文件名是类名除去开头的类标志“C”。
图6-14 新增对话框类及文件
在创建新类的时候,要注意新类的对话框ID一定要与对话框资源ID一致,这些ID告诉对话框类,在对话框窗口创建前,哪一个对话框资源要被检查,初始化控件并显示。
尤其在创建好对话框后,不能随意地改动对话框资源ID和删除对话框资源。
6.3.2 创建对话框成员变量
创建好一个对话框类后,可以增加类的成员变量来操作对话框上的控件。
出于不同的操作目的,MFC提供了两种类型的成员变量,如表6-1所示。
表6-1 对话框类的成员变量类型
类型描述
Values 值类型的成员变量。
用于控件的值控制,可以有多种数据类
型,由所连接的控件类型决定。
例如,Edit Box控件可以有
CString型或int型。
Radio Button可以是int型。
Controls 控件类型的成员变量,实质是该控件类的一个对象。
创建了
一个控件对象,就可以通过该对象使用控件类的方法对控件
进行操作,例如,在程序运行时为Combo Box加入选择项,
设置控件是否有效或可见等。
例如,创建了CScoreDlg类后,需要为对话框中每一个Edit Box控件创建一个值类型的成员变量,来取得用户在EditBox输入的数据,增加控件成员变量的步骤如下:
(1)打开ClassWizard窗口,选择Member Variables标签页,Class name下拉列表中选择CScoreDlg
类。
这时,对话框中可以创建成员变量的控件ID出现在下方的Control IDs列表中,如图6-15所示。
图6-15 增加一个对话框类的成员变量
(2)选择一个IDC_SCORE1,单击Add Variable按钮,弹出Add Member Variable对话框,Member
variable name编辑框中填写变量名为:m_score1,确认Category下拉框中为:V alue,在Variable type下拉框中选择为:int。
(3)单击OK按钮,回到ClassWizard窗口,可以看到新增的成员变量出现在列表中。
同样的操作增
加其它四个成员变量。
(4)如果增加成员变量时操作有误,例如变量名错误,变量类型错误,选择该成员变量,单击Delete
Variable按钮删除该变量,再重新创建。
创建好的成员变量如图6-16所示。
变量类型变量名称
图6-16 成员变量列表
创建好成员变量后,我们来检查一下ClassWizard作了哪些工作:
(1)展开项目工作区的ClassView面板中的CScoreDlg类,在树目录上出现了刚创建的成员变量。
(2)双击CScoreDlg的类名,进入该类的头文件ScoreDlg.h,可以找到对话框类定义的代码,如程
序清单6-1中所示。
程序清单6-1:对话框成员变量定义示例
class CScoreDlg : public CDialog
{
// Construction
public:
CScoreDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CScoreDlg)
enum { IDD = IDD_DIALOG1 };
int m_score1;
int m_scroe2;
int m_score4;
int m_score5;
int m_score3;
//}}AFX_DATA
... ...
}
其中呈灰色显示的,在宏“{{AFX_DA TA(CScoreDlg)......}}AFX_DATA”之间定义的是用ClassWizard 创建的成员变量。
需要注意的是,所有ClassWizard 产生的灰色显示的代码,不要在文件中直接修改,而应在ClassWizard工具中进行修改,不然容易引起错误。
(3)打开该类的构造函数,可以看到ClassWizard自动加入了成员变量的初始化代码,如程序清单
6-2所示。
程序清单6-2:对话框类的构造函数
CScoreDlg::CScoreDlg(CWnd* pParent /*=NULL*/)
: CDialog(CScoreDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CScoreDlg)
m_score1 = 0;
m_scroe2 = 0;
m_score4 = 0;
m_score5 = 0;
m_score3 = 0;
//}}AFX_DATA_INIT
}
6.3.3 对话框数据交换和校验
对话框的值类型的成员变量存储了与控件相对应的数据,对框话打开时,用户可以修改控件的数据,有时需要应用程序对用户的输入进行及时反馈,这时数据成员变量需要与控件交换数据,以完成输入输出功能。
对于这种功能MFC是靠CDataExchange类提供的数据交换(DDX:Dialog Data Exchange)机制来完成的,该类提供了数据有效机制(DDV:Dialog Data Validation)
当在对话框类中增加一个数据成员变量,有时需要规定数据的有效性校验规则,例如,成绩录入对话框中,应设置各门课的成绩应在0-100的范围内。
在应用程序运行的时候,当用户输入数据拷贝到数据成员变量时,DDV机制被调用,如果有效性校验失败,即用户输入一个不合理的数据时,将出现一个错误信息对话框,并返回到出现错误输入的控件。
有效性校验的设置也是在ClassWizard中完成的。
我们再回到成绩录入的Member Variables标签页,选择表示成绩输入框的m_score1,在标签页的下方会出最大值和最小值的输入框,如图6-17所示,填入0和100。
如果一个CString型的数据成员变量对应的通常是字符串的长度。
图6-17 添加数据成员变量的有效范围
对话框类调用DoDataExchange函数来实现DDV和DDX,对应图6-17的CScoreDlg类的DoDataExchange代码如程序清单6-3所示。
程序清单6-3:对话框类的DoDataExchange函数
void CScoreDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CScoreDlg)
DDX_Control(pDX, IDOK, m_OK); //控件对象数据交换
DDX_Control(pDX, IDC_SCORE5, m_Score5Edit); //文本框数据交换
DDX_Control(pDX, IDC_SCORE4, m_Score4Edit);
DDX_Control(pDX, IDC_SCORE3, m_Score3Edit);
DDX_Control(pDX, IDC_SCORE2, m_Score2Edit);
DDX_Control(pDX, IDC_SCORE1, m_Score1Edit);
DDX_Text(pDX, IDC_SCORE2, m_score2);
DDX_Text(pDX, IDC_SCORE3, m_score3);
DDX_Text(pDX, IDC_SCORE4, m_score4);
DDX_Text(pDX, IDC_SCORE5, m_score5);
DDX_Text(pDX, IDC_SCORE1, m_score1);
DDV_MinMaxInt(pDX, m_score1, 0, 100); //最大最小值检查
//}}AFX_DATA_MAP
}
pDX指针指向一个CDataExchange对象,DDX函数来完成控件和数据成员变量之间的数据交换,DDV完成数据有效性检查。
DDX和DDV适用于文本框、复选框、单选按钮、列表框和组合框。
当程序需要交换数据时,不需要编写代码调用DoDataExchange函数,而应该调用CWnd::UpdateData()函数,UpdateData()函数内部调用了DoDataExchange函数。
UpdateData()函数只有一个BOOL类型的参
数,决定数据交换的方向:
(1) UpdateData (false )
将对话框对象的数据成员变量的值拷贝到对话框中的控件。
(2) UpdateData (true )
将对话框中控件的值拷贝到对话框对象的数据成员变量。
你可以随时在需要进行数据交换时调用相应的UpdateData()函数,例如,在成绩录入的对话框中增加两个控件,一个是Edit Box 用于显示总分,另一个是Button 用于计算总分,则在Button 的Click 事件处理函数中,就需要先调用UpdateData(true)获取用户录入的5门功课的成绩,在计算总分后,调用UpdateData(false),将总分显示在Edit Box 中。
在默认的CDialog::OnInitDialog()函数中调用了UpdateData(false),这样在对话框创建的时候,数据成员的初值就会反映到相应的控件上。
若用户单击OK (确定)按钮关闭对话框,CDialog::OnOK()函数会调用UpdateData(true),将控件中的数据传给数据成员变量,如图6-18所示。
图中说明了对话框的控件与对话框对象之间的数据交换是由框架自动完成的,而对话框对象与文档对象之间的数据交换则需要编写代码。
图6-18 数据交换和验证在应用程序中的实现
6.4 运行对话框
创建好一个对话框资源和对话框类,要在应用程序中运行对话框,通常要在一个菜单命令下打开一个对话框。
所以,首先要定义一个菜单项和相应的菜单命令处理函数,在函数中编写代码运行对话框。
运行模式对话框和无模式对话框有所不同,下面结合实例详细介绍两种对话框运行的方法。
6.4.1模式对话框
在应用程序中使用得更多的还是模式对话框,模式对话框的运行分两个步骤: (1) 创建一个对话框对象
(2) 调用CDialog::DoModal()函数打开对话框
DoModal()函数负责模式对话框的创建和撤消。
在创建对话框时,DoModal()的任务包括:装载对话框资源、调用OnInitDialog()初始化对话框和将对话框显示在屏幕上。
完成对话框的创建后,DoModal()启动一个消息循环,以响应用户的输入。
这时,用户只能与对话框进行交互,其它用户界面对象收不到输入信息,只有终止模式对话框后才能进行其它工作。
若用户在对话框内单击了系统默认的OK (确定)按钮,则CDialog::OnOK()函数将被调用,OnOK()首先调用UpdateData(true)函数,将数据从对话框中的控件拷贝到数据成员变量,再调用
DDX
Public: data member
document
xxxxxxx xxxxxxx xxxxxxx xxxxxxx
框架处理对话框和对象之间的数据交换和验证
编写代码在文档对象和对话框对象之间交换数据
DDX and DDV
CDialog::EndDialog()关闭对话框,并返回值IDOK。
若用户在对话框单击了系统默认的Cancel(取消)按钮,则CDialog::OnCancel()函数将被调用,该函数只调用CDialog::EndDialog()关闭对话框,并返回值IDCANCEL。
程序可以根据返回值是IDOK还是IDCANCEL来判断用户关闭对话框按的哪一个键。
下面我们将运行成绩录入对话框,当按“确定”按钮返回时,将其显示在主窗口视图上。
为此,要定义对应的文档对象。
步骤如下:
1.增加文档类公有变量并设置初值
int型成员变量数组score[5],存放5门课程成绩;int型成员变量TScore,用来存放总分。
在构造函数中设置数组score和TScore的初值都为0。
2.在视图类OnDraw函数中添加代码实现成绩的输出
具体代码见程序清单6-4所示粗体部分。
程序清单6-4:OnDraw函数输出int型文档类成员变量的值
void CExam6_1View::OnDraw(CDC* pDC)
{
CExam6_1Doc* pDoc = GetDocument();
ASSERT_V ALID(pDoc);
// TODO: add draw code for native data here
pDC->TextOut(0,0,"高等数学大学物理大学英语哲学计算机基础总分") ;//输出表头
CString str;//将int型数据转换为格式字符串
str.Format("%10d%16d%16d%16d%16d%18d",pDoc->score[0],pDoc->score[1],
pDoc->score[2],pDoc->score[3],pDoc->score[4],pDoc->TScore );
pDC->TextOut(0,20,str); //输出成绩
}
3.增加一个菜单项
在“编辑”菜单的最下面增加一个菜单项,Caption 为“成绩录入”,菜单ID为ID_SCOREFILLING。
4.为新增菜单在文档类定义消息处理函数
用ClassWizard在文档类生成菜单命令处理函数OnScorefilling()。
5.编辑代码完成下面的功能
(1)创建对话框对象。
(2)运行成绩录入对话框,并把对话框数据成员的值拷贝到文档类成员变量score数组中。
(3)计算总分。
(4)更新视图。
具体代码见程序清单6-5所示粗体部分。
程序清单6-5:调用模式对话框示例
void CExam6_1Doc::OnScorefilling()
{
// TODO: Add your command handler code here
CScoreDlg dlg; //创建对话框对象
if(dlg.DoModal()==IDOK )//调用对话框并判断返回值为IDOK
{ //使用对话框对象的成员变量的值修改文档对象的成员变量
score[0]=dlg.m_score1 ;
score[1]=dlg.m_score2 ;
score[2]=dlg.m_score3 ;
score[3]=dlg.m_score4 ;
score[4]=dlg.m_score5 ;
for(int i=0;i<5;i++) //计算总分
TScore+=score[i];
this->UpdateAllViews(NULL); //更新视图
}
}
6.加入头文件
在Exam6_1Doc.cpp文件的头部的所有的include语句之后加入语句:#include “ScoreDlg.h”
7.编辑运行程序
执行菜单命令“编辑”->“成绩录入”,弹出“成绩录入”对话框,输入各门课的成绩后,按“确定”退出对话框,应用程序主窗口中显示刚刚输入的各课成绩和总分。
6.4.2对话框初始化
对话框的初始化工作包括:为控件赋初始值(如:文本框的显示值,单选按钮,复选框的选中状态等),或者设置控件的初始状态(如:控件是否可用、是否显示,下拉框中的选择项等)。
为控件赋初始值也就是为对话框对象的数据成员变量赋初值,可在两个位置进行:
1.对话框类的构造函数
系统一般在对话框类的构造函数中,为数据成员变量赋初值。
2.对话框对象创建后
对话框对象一般在一个菜单命令处理函数中创建,创建后在对话框调用之前,也就是在DoModal ()函数调用之前,可以通过对象调用数据成员变量为其赋初值。
修改程序清单6-5中的OnScorefilling()函数,实现每次调用成绩录入对话框时,以文档对象score 数组中现有的成绩为初始值,作为对当前视图的修改。
增加的代码见程序清单6-6所示粗体部分。
程序清单6-6:模式对话框数据成员赋初值
void CExam6_1Doc::OnScorefilling()
{
// TODO: Add your command handler code here
CScoreDlg dlg;//创建对话框对象
dlg.m_score1=score[0]; //初始化对话框数据成员
dlg.m_score2=score[1];
dlg.m_score3=score[2];
dlg.m_score4=score[3];
dlg.m_score5=score[4];
if(dlg.DoModal()==IDOK )
{score[0]=dlg.m_score1 ;
score[1]=dlg.m_score2 ;
score[2]=dlg.m_score3 ;
score[3]=dlg.m_score4 ;
score[4]=dlg.m_score5 ;
for(int i=0;i<5;i++)
TScore+=score[i];
this->UpdateAllViews(NULL);
}
}
修改后再次编译运行程序,可以看到每次对话框打开时,控件的初值都能反应当前视图的显示。
程序清单6-6也给出的调用对话框的一个范例,一般遵循四个基本步骤:
(1)创建对话框对象
(2)初始化对话框
(3)调用对话框
(4)确定返回后的处理
图6-18中文档对象和对话框对象之间交换数据通常是在第(2)、(4)步编写代码完成的。
设置控件的初始状态,可以直接在对话框资源中各控件的属性对话框中进行,更灵活地方式是在对话框类的OnInitDialog()函数中进行控件的设置。
默认情况下,OnInitDialog()函数不出现在对话框类中,需要映射对话框类的WM_INITDIALOG窗口消息。
下面继续修改应用程序Exam6_1,实现功能:打开成绩录入对话框时,“确定”按钮不可用,当任意一个Edit Box 的内容修改后,“确定”按钮可以使用。
实现步骤如下:
(1)打开ClassWizard的Member Variables标签页,增加数据成员变量如表6-2所示。
表6-2 EX6数据成员变量设置
(2)打开ClassWizard的Message Maps标签页,Class name中选择CScoreDlg类,Objects IDs中选
择CScoreDlg,Messages中选择WM_INITDIALOG窗口消息,单击Add Function按钮。
在对话框类CScoreDlg中增加了成员函数OnInitDialog()。
(3)增加代码如程序清单6-7所示粗体部分。
使对话框显示时,“确定”按钮灰色显示不能使用。
程序清单6-7:初始化对话框函数示例
BOOL CScoreDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
m_OK.EnableWindow (false);//禁止“确定”按钮使用,灰色显示。