与对话框编程教学.ppt
《与对话框编程教学.ppt》由会员分享,可在线阅读,更多相关《与对话框编程教学.ppt(161页珍藏版)》请在三一办公上搜索。
1、第五章 MFC 与对话框编程,5.1 对话框的基本原理 对话框是 Windows 应用程序 GUI 界面的一个重要组成部分,它的主要功能:接收用户的输入(数据和操作、控制命令);输出用户关心的状态信息(操作的结果数据和状态)。在对话框中,可以放置各种必要的控件,所有与用户的交互 操作都是通过这些控件实现的。在 MFC 中,对话框的基本属性和行为由 CDialog 类描述,该类的基类为 CWnd,因此,它继承了窗口类的所有属性和功能,并且增加了交互操作所需要的数据交换特性。放置在对话框中的各类控件,MFC 都有相应的类来描述,所有控件类的基类都是 CWnd。CDialog 类和所有控件类的派生层
2、次结构如下:,由此我们可以看出:对话框可以视为是提供了一个能放置多个子窗口,并提供了窗口之间通讯操作的窗口框架。这种异类同构的结构有利于简化构造和便于通讯。,CObject,对话框和放置在其中的控件的创建,MFC 应用程序是从两个方面实现的:对话框模板资源:描述对话框本身和各个控件的类型、外观 属性和控件在对话框中的分布信息。使用资源编辑器绘制模 板,并将相关的信息保存在资源文件(扩展名为“.rc”)中。对话框类:封装对话框的属性和操作功能。保存在相应的定 义和实现文件中。注意,与所有 CWnd 及其派生类对象一样,对话框类对象必须与对话框模板所描述的 Windows 窗口相关联后,所有施加于
3、对话框的操作才是合法的。,对话框的设计步骤一般是先设计对话框模板,然后定义与对话框模板资源相关联的对话框类。对话框的使用分为模态对话框和非模态对话框两种:模态对话框:对话框打开时,用户只能在对话框中进行交互 操作,只有对话框关闭后,才能进行其他用户界面的操作。非模态对话框:打开对话框进行操作的同时,仍然可以进行 其他用户界面的交互操作。,5.2 创建模态对话框 创建一个名为“Register”SDI 应用程序,用于人员信息的注册登记。该应用程序项目除视图的基类选择 CEditView 外,其他均接受缺省选择。5.2.1 创建对话框模板资源 为项目添加一个对话框模板(缺省命名为 IDD_DIAL
4、OG1)。从控件选择面板上选择所需要的控件,将它放置到对话框模板中你所希望的设计位置上。对话框和对话框中的每个控件都可以通过“属性”对话框设置它们的属性和风格。选中对话框或某个控件,点击鼠标右键便会弹出一个浮动上下文菜单:,选择菜单项 Properties,便弹出选中对话框或控件的属性操作对话框:,操作选择标签的个数和类型随着选中的对象(对话框或不同控件)的不同而不同,但其中最右边的两个按钮和第一项标签是相同的。1 按钮:按下该按钮,使按钮变成,使得该属性对话框 保持可见(Keep Visible),直到释放该按钮或强制关闭对话框。属性对话框的内容会随着当前选中对象的改变而变化。2 按钮:点击
5、该按钮,将显示当前选中属性页面相关内容的 帮助信息。,3 通用标签:提供对话框或所有控件的通用属性操作。对话框的主要通用属性操作:ID指定对话框的标识值,程序可使用它装载对话框资源和选取对话框窗口。Caption指定对话框的显示标题。Font选择对话框中所有文本(包括控件标题)字体。Menu如果需要,可为对话框选择显示菜单资源。控件的通用属性的含义如下:ID指定控件的标识值,程序使用它装载控件资源和选取控件窗口。,Caption指定诸如静态文本、组框、按钮、复选框、单选按钮等控件的显示标题。对于能发出通知消息的控件,其标题与菜单项标题一样,紧跟字符&之后的字符在运行时具有下划线,可通过按Alt
6、+下划线字符替代点击该控件。Visible指定控件被创建后是否可见。Disable指定控件被创建后是处于允许还是被禁止使用。Tab stop对话框运行时,允许用户使用Tab 键顺序选中具有该属性的控件。控件选中顺序可以任意指定。,Group用来指定一组控件(例如单选按钮),用户可以用箭头键在组内的控件之间移动选择;在同一组内的单选按钮具有互斥性,即只能选中一个单选按钮。如果一个控件具有Group 属性,则这个控件以及按Tab 顺序紧随其后的的所有控件都属于同一组,直到另一个有Group 属性的控件为止。本例中对话框的具体设计步骤如下:1 修改对话框模板资源的标识为 IDD_REGISTER。2
7、 在对话框中添加控件,3 设置控件的 Tab 顺序4 测试对话框效果,对话框类的创建 使用 ClassWizard 创建与对话框模板资源 IDD_REGISTER 相关联的对话框类 CRegisterDialog,其基类为 CDialog。为对话框类加入成员变量 对话框的主要功能就是要完成数据信息的输入输出,用户通过控件输入的数据信息需要存放在相应的数据对象中,才能被程序读取使用;程序通过控件输出的数据信息也需要先存储到相应数据对象中,才能被送到对应的控件显示。,这些数据对象相当于控件与用户或程序之间交换数据信息的缓冲区,所以在对话框类中增加与对话框模板中控件对应的数据对象是必要的。控件所对应
8、的数据对象有两类:一类是控件所对应的 MFC 类对象(控件类对象)可以用于对 控件的功能的调用;另一类是数值类对象,用于数据信息的交换。常用控件所对 应的数值类对象如下:,为控件定义哪一类数据对象,或是两类数据对象都定义将根据控件在对话框类中的使用情况而定。具体的添加方法:在 Visual C+6.0 中,使用 ClassWizard 的Member Variables属性页完成。添加方法如下:,在对话框中选中要添加数据对象的控件 ID,双击被选项或点击 按钮,弹出“Add Member Variable”对话框:,在该对话框中可以确定你所要添加的数据对象的种类是数值类对象还是控件类对象,并为
9、所添加数据对象命名(推荐命名规则:m_+数据对象类型缩写+数据对象含义,例如 m_nWork)。本例在 CRegisterDialog 中增加的数据对象如下:,在 Visual C+.NET 中,是通过在对话框模板中,为每个需要添加对象成员的方法实现的。具体的添加方法如下图所示:,对话框的初始化 对话框初始化是在对话框类构造函数和对话框窗口初始化成员函数 OnInitDialog 中完成的。构造函数只完成数据成员的初始化,因为此时对话框类对象 正在创建中,而对话框窗口还未创建,窗口句柄无效。如果 需要初始化的数据对象是通过 ClassWizard 的 Member Variables 页添加的
10、,则构造函数中数据对象的初始化代码将会由 ClassWizard 自动添加(当然可以根据需要修改这些代码)。例如:,CRegisterDialog:CRegisterDialog(CWnd*pParent/*=NULL*/):CDialog(CRegisterDialog:IDD,pParent)/AFX_DATA_INIT(CRegisterDialog)m_nAge=0;m_strIncome=_T();m_strKind=_T();m_bMarried=FALSE;m_strName=_T();m_nSex=-1;m_strUnit=_T();m_nWork=-1;/AFX_DATA_I
11、NIT,OnInitDialog 虚函数是窗口消息 WM_INITDIALOG 的响应函数。当对话框对象收到此消息时,对话框窗口已创建完成,对话 框窗口句柄已经有效,但对话框还没有被显示,对话框窗口 中的控件也已被创建。这意味着在重新定义的 OnInitDialog 中 可以添加一些影响对话框(包括控件)外观的初始化和对话 框构造函数无法完成的初始化工作。OnInitDialog 对对话框的 作用与 OnCreate 对 CMainFrame 对象的作用类似。本例中,首 先使用 ClassWizard 为 CRegisterDialog 添加对 WM_INITDIALOG 消息映射和处理函数
12、OnInitDialog(注意,在 Visual C+.NET 中 是通过重载基类的虚函数 OnInitDialog 的方法完成的),然后 手工在 OnInitDialog 中加入对用于工资收入的列表框控件的初 始化代码如下:,BOOL CRegisterDialog:OnInitDialog()CDialog:OnInitDialog();/TODO:Add extra initialization here m_ctrlIncome.AddString(500元以下);m_ctrlIncome.AddString(500-1000元);m_ctrlIncome.AddString(1000
13、-2000元);m_ctrlIncome.AddString(2000元以上);return TRUE;/return TRUE unless you set the focus to a control/EXCEPTION:OCX Property Pages should return FALSE,信息交换、验证 在对话框操作时,用户只要通过交互方式修改对话框窗口某个控件中的数据信息,就可以修改与该控件关联数值对象的值;反过来只要程序修改了对话框类对象中某个与控件关联数值对象的值,也就可以修改对话框窗口中与该数值对象关联控件中显示的信息。对话框的这种数据交换(DDX)和数据有效验证(DDV
14、)能力是由 MFC 类 CDataExchange 来实现的。实现这种信息交换操作是由虚函数 CDialog:DoDataExchange完成的。派生类中该函数的重定义版本将在调用该函数的基类版本基础上完成派生类对象所需要的特定的数据交换操作。所幸的是该函数的重定义工作可以借助 ClassWizard 在定义与控件相关的对话框类数据对象的同时自动完成的。例如在本例中:,void CRegisterDialog:DoDataExchange(CDataExchange*pDX)CDialog:DoDataExchange(pDX);/AFX_DATA_MAP(CRegisterDialog)DD
15、X_Control(pDX,IDC_INCOME,m_ctrlIncome);DDX_Text(pDX,IDC_AGE,m_nAge);DDV_MinMaxUInt(pDX,m_nAge,0,150);DDX_LBString(pDX,IDC_INCOME,m_strIncome);DDX_CBString(pDX,IDC_KIND,m_strKind);DDV_MaxChars(pDX,m_strKind,15);DDX_Check(pDX,IDC_MARRIED,m_bMarried);DDX_Text(pDX,IDC_NAME,m_strName);,DDV_MaxChars(pDX,m
16、_strName,15);DDX_Radio(pDX,IDC_SEX,m_nSex);DDX_Text(pDX,IDC_UNIT,m_strUnit);DDV_MaxChars(pDX,m_strUnit,30);DDX_Radio(pDX,IDC_WORK,m_nWork);/AFX_DATA_MAP,由于对话框的数据交换是双向的,所以参数 pDX 所指向的CDataExchange 类对象含有数据的传递方向。实现数据交换不是直接调用 DoDataExchange(因为无法确定数据传递方向),而是调用 CWnd:UpdateData。UpdateData 的原型如下:BOOL UpdateD
17、ata(BOOL bSaveAndValidate=TRUE);参数:bSaveAndValidate=TRUE 指定数据值从控件传递到数据对象;bSaveAndValidate=FALSE 指定数据值从数据对象传递到控件。该函数调用了 DoDataExchange,显然,参数 bSaveAndValidate 确定了 DoDataExchange 的数据传递方向。,对话框的运行在程序中运行模态对话框的步骤:在栈上构建一个局部对话框类对象。调用CDialog:DoModal()DoModal 负责模态对话框的创建启动一个消息循环撤消 对话框(接收到 按钮或 按钮控件发出的消 息)。显然,在 D
18、oModal 函数返回之前,不可能进行其他界 面上的操作的。该函数是一个虚函数,意味着可以根据需要 在 CDialog 的派生类中定义特定功能的 DoModal,但大多数 情况下无须重新定义。对话框创建时,程序框架会自动调用 OnInitDialog 初始化 对话框,并调用 UpdateData(FALSE)初始化控件的显示。,对话框撤消时,分为两种情况:按 按钮,消息处理成员函数 OnOk 被调用。在该函数的执行中,首先调用 UpdateData(TRUE)将控件中的数据传递到相应数据对象中保存起来,然后调用 EndDialog 关闭对话框,并返回标志值 IDOK。按 按钮,消息处理成员函数
19、 OnCancel 被调用,在该函数的执行中,只调用 EndDialog 关闭对话框,并返回标志值 IDCANCEL。根据 DoModal 返回的标志值,程序就可以知道对话框是如何 结束的(按 或 按钮),从而确定后续操作。,在本例中,为了模态使用对话框,添加了一条菜单命令来触发对话框类对象的创建,对话框的模态创建、显示、操作和根据对话框结束状态的后续操作。1 在菜单资源中的 Edit 弹出式菜单中添加菜单项“登录数据”,其标识为 ID_EDIT_REGISTER。2 使用 ClassWizard 为菜单项“登录数据”在视图类 CRegisterView 中定义命令消息映射项和处理函数 OnE
20、ditRegister。3 定义函数 OnEditRegister 实现代码:,void CRegisterView:OnEditRegister()/TODO:Add your command handler code here CRegisterDialog dlg;if(dlg.DoModal()=IDOK)CString str;GetWindowText(str);/获取视图窗口原有文本内容 str+=rn;str+=姓名:;str+=dlg.m_strName;str+=rn;str+=性别:;str+=dlg.m_nSex?女:男;str+=rn;str+=年龄:;CString
21、 str1;str1.Format(%d,dlg.m_nAge);,str+=str1;str+=rn;str+=婚否:;str+=dlg.m_bMarried?已婚:未婚;str+=rn;str+=就业情况:;str+=dlg.m_nWork?下岗:在职;str+=rn;str+=工作单位:;str+=dlg.m_strUnit;str+=rn;str+=单位性质:;str+=dlg.m_strKind;str+=rn;str+=工资收入:;str+=dlg.m_strIncome;str+=rn;SetWindowText(str);/在视图窗口中显示新文本 4 在 CRegisterVi
22、ew 的实现文件中加入:#include“RegisterDialog.h”5 编译运行,5.2.7 程序的改进 在程序的运行中发现存在这样的缺点:当在“就业情况”组框中选择了单选按钮“下岗”,而“单位情况”组框中的所有控件仍然有效,显然这是不合理的,会引起登录数据的错误。为了克服这一缺点,应该当在“就业情况”组框中选择了单选按钮时,程序能够响应对应的控件消息,在消息处理函数中根据所选按钮的不同,使“单位情况”组框中的相关控件允许或禁止。虽然组框中的单选按钮是两个,而它们的消息处理函数只需要一个,因此应该使用 ON_CONTROL_RANGE 消息映射宏进行消息映射。不幸的是 ClassWiz
23、ard 不支持 ON_CONTROL_RANGE,所以我们必须按下列步骤手工创建单选按钮的消息映射和消息处理函数。,1 在 CRegisterDialog 的定义文件中定义消息处理函数原型:class CRegisterDialog:public CDialog/Implementation protected:/Generated message map functions/AFX_MSG(CRegisterDialog)virtual BOOL OnInitDialog();/AFX_MSG afx_msg void OnWorkClicked(UINT nCmdID);DECLARE_M
24、ESSAGE_MAP();,2 在 CRegisterDialog 实现文件的消息映射表中加入映射条目:BEGIN_MESSAGE_MAP(CRegisterDialog,CDialog)/AFX_MSG_MAP(CRegisterDialog)/AFX_MSG_MAP ON_CONTROL_RANGE(BN_CLICKED,IDC_WORK,IDC_WORK1,OnWorkClicked)END_MESSAGE_MAP(),3 在 CRegisterDialog 实现文件中添加消息响应函数实现代码:void CRegisterDialog:OnWorkClicked(UINT nCmdID)
25、if(IsDlgButtonChecked(IDC_WORK)/选中“在职”单选按钮否?/使“单位情况”组框中的相关控件有效 GetDlgItem(IDC_UNIT)-EnableWindow(TRUE);GetDlgItem(IDC_KIND)-EnableWindow(TRUE);m_ctrlIncome.EnableWindow(TRUE);,else/清除文本框内容,并使之禁止 GetDlgItem(IDC_UNIT)-SetWindowText();GetDlgItem(IDC_UNIT)-EnableWindow(FALSE);/使组合框处于未选择状态,并使之禁止 CComboBo
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 对话框 编程 教学
链接地址:https://www.31ppt.com/p-6237314.html