返回 1
第五章 对话框及常用控件本章导读在 Windows应用程序中,对话框 ( Dialog) 是最重要的用户界面元素之一,是应用程序与用户交互的重要手段 。 当用户进行某项操作之后,弹出一个对话框把反馈信息传递给用户,也可以要求用户输入数据或者进行选择 。
控件在 Windows应用程序中也很常见 。 一般来说,
在对话框中是通过各种控件来和用户进行交互的,我们经常用到的控件有按钮,列表框,编辑框,组合框,
滚动条等 。 实际上,控件是一种特殊类型的窗口,通常为其父窗口所拥有 。
返回 2
5.1 对话框的组成和分类
5.1.1 对话框的组成在 Visual C++中,对话框主要是由对话框资源和对话框类组成:
1,对话框资源对话框资源中描述的是对话框的大小,风格等特性,
以及对话框中控件的类型和它们的位臵 。 定义对话框资源最简单,最有效的方法就是使用 Visual C++中的资源编辑器 。
2,对话框类对话框资源所提供的仅仅是一个数据结构,要利用所创建的对话框资源,必须要创建以它作为资源的对话框类,对话框类是从 CDialog类中派生出的子类,它提供了编程接口来管理对话框 。
返回 3
5.1 对话框的组成和分类
5.1.2 对话框的分类对话框有两种类型:模式对话框和无模式对话框 。 下面分别对这两种对话框进行说明 。
1,模式对话框所谓,模式对话框,是指对话框被弹出后,用户必须在对话框中作出相应的操作;在退出对话框之前,会阻止其他应用程序的运行 ( 包括它所在的应用程序 ) 。
一般情况下,模式对话框会有 【 OK】 ( 确定 ) 和
【 Cancel】 ( 取消 ) 两个按钮 。 单击 【 OK】 按钮,系统认定用户在对话框中的选择或输入有效,退出对话框;
单击 【 Cancel】 按钮,系统认定用户在对话框中的选择或输入无效,退出对话框,程序恢复原有状态 。
返回 4
5.1 对话框的组成和分类
2,无模式对话框所谓,无模式对话框,是指当对话框被弹出后,将一直保留在屏幕上,但不影响其他应用程序的运行,用户可以继续在对话框所在的应用程序中进行其他操作;
当需要使用对话框时,只需像激活一般窗口一样单击对话框所在的区域即可。例如在 Microsoft Word中的,查找,和,替换,对话框。
两种对话框在用资源编辑器设计和使用 Class Wizard
进行编程时的方法基本一致 。 但在创建和退出窗口时的方式有所不同 。
返回 5
5.1 对话框的组成和分类
1,在创建时,模式对话框是由系统自动分配内存空间,
因此在退出对话框时,对话框对象会自动删除 。 而无模式对话框则是需要用户来指定内存,退出时还需用户自己来删除对话框对象 。
2,在退出时,两种对话框所使用的终止函数不一样 。
模式对话框通过调用 CDialog::EndDialog来终止,而无模式对话框则是通过调用 CWnd::DestroyWindow
来终止 。
返回 6
5.2 创建模式对话框
5.2.1 创建应用程序框架在进行创建对话框之前,我们首先按照第四章介绍的方法创建一个应用程序框架,并且在 Visual C++ 6.0中将
,工程,打开 。
步骤一,在 Visual C++ 6.0中选择 【 File】 菜单的 【 New】
菜单命令,弹出 【 new】 对话框 。 在工程列表中选中选项
【 MFC AppWizard[exe]】,在 【 Project name】 栏中输入工程名称为 【 Dialog】,在 【 Location】 栏中指定工程的存储路径为 E:\C++\EXAMPLE\。 单击 【 OK】 按钮启动 App
Wizard。
步骤二,在接下来的 AppWizard的各个步骤中按下列要求设臵选项:
返回 7
5.2 创建模式对话框
Step 1,选择单文档界面 ( Single Document),其他接受系统缺省设臵,单击 【 Next】 按钮,进入下一步 。
Step 2,接受系统缺省设臵,单击 【 Next】 按钮
Step 3,关闭 【 ActiveX Controls】 复选框选项,单击 Next】
按钮,进入下一步 。
Step 4,关闭 【 Docking toolbar】,【 Initial status bar】,
【 Printing and print preview】,以及 【 3D Control】 复选框选项,单击 【 Next】 按钮,进入下一步 。
Step 5,接受系统缺省设臵,单击 【 Next】 按钮 。
Step 6,接受系统缺省设臵,单击 【 Finish】 按钮 。
最后,弹出工程信息对话框,单击 【 OK】 按钮,完成应用程序框架的设计 。
返回 8
5.2 创建模式对话框
5.2.2 创建对话框资源接下来,我们要做的工作是创建对话框资源,其创建步骤如下:
步骤一,在打开的工程中,选择 【 Insert】 菜单中的
【 Resource】 菜单项,或直接按 Ctrl+R键,系统将弹出
【 Insert Resource】 对话框步骤二,在对话框中选择 【 Dialog】 选项,然后单击
【 New】 按钮,或直接双击 【 Dialog】 选项,这时对话框资源编辑器将显示在 Visual C++平台中,在对话框资源编辑器中显示了一个只有 【 OK】 按钮和 【 Cancel】 按钮的简单的对话框。
返回 9
5.2 创建模式对话框在新建对话框的同时,在其右边随之出现了一个控件模板,即 Controls工具栏,它的作用是向对话框资源中添加控件。工具栏中的每一个图标(除了左上角的指针)
都代表一种能够添加到对话框中的控件,我们可以用一种,所见即所得,的方式来向对话框资源添加各种控件。
如果仔细观察一下系统的菜单,你就会发现菜单中多了一项 【 Layout】 菜单,而且在状态拦的上面增加了一个新的工具栏 —— 【 Dialog】 工具栏,其中的按钮在编辑对话框资源和增加控件时是十分有用的工具。下面我们对
【 Dialog】 工具栏进行详细的说明。
返回 10
5.2 创建模式对话框
1,Test:单独运行对话框来测试对话框的外观和行为;
2,Align Left,将选定的多个控件按照左对齐的格式放臵;
3,lign Right:将选定的多个控件按照右对齐的格式放臵
4,Align Top:将选定的多个控件按照上对齐的格式放臵
5,Align Botton:将选定的多个控件按照下对齐格式放臵
6,Central Vertical:将选定的一个或多个控件按照中心垂直对齐格式放臵
7,Central Horizontal,将选定的一个或多个控件按照中心水平对齐格式放臵
8,Space Across:将选定的多个控件两两之间的水平间隔相同返回 11
5.2 创建模式对话框
9,Space Down:将选定的多个控件两两之间的垂直间隔相同
10,Make Same Width:使选定的多个控件具有相同的宽度,
宽度的标准是最后选择的控件
11,Make Same Height:使选定的多个控件具有相同的高度,
高度的标准是最后选择的控件
12,Make Same Size:使选定的多个控件具有相同的高度和宽度,高度和宽度的标准是最后选择的控件
13,Toggle Grid:显示或隐藏网格
14,Toggle Guides:显示或隐藏标尺返回 12
5.2 创建模式对话框步骤三,系统默认产生的对话框的标题是,Dialog”,下面我们来更改一下对话框的标题 。
选择 【 View】 菜单下的 【 Properties】 菜单项,或对话框窗体上单击鼠标右键,在弹出的快捷菜单中选
【 properties】 菜单项,系统将弹出对话框资源的属性对话框 。 选择 【 General】 选项卡,在其中的 【 Caption】
框中输入对话框标题的名称为,个人资料,。 资源 【 ID】
框中的默认值为 IDD-DIALOG1,可以按照自己的需要修改为便个于记忆的标识符 。 因为此对话框的内容主要用于显示人资料,所以在此示例中,我们将 【 ID】 改为
,IDD_DIALOG_M ydata” 。 按,回车,键,完成对话框标题和 ID的更改 。
返回 13
5.2 创建模式对话框在 Visual C++中,对于不同的控件定义了不同的 ID 类型,IDC_是控件的 ID 值 (ID of Control) 的前缀; IDD_
是对话框的 ID值 ( ID of Dialog) 的前缀; ID是系统自己缺省的 ID值的前缀 。
步骤四,向对话框中添加控件 。 向对话框中添加控件的方法有两种:
1,在控件工具栏中选择所需要的控件,按下鼠标的左键
( 不要松开 ),将鼠标拖到对话框中松开,在对话框中将添加一个指定的控件 。
2,在控件工具栏中单击所需要的控件,此时控件将呈凹下状态,将鼠标移至对话框,鼠标此时显示为,十,字形,按下鼠标左键,在对话框上拖动至适当大小,松开鼠标左键,开鼠标左键,在对话框中将添加一个指定的控件 。
返回 14
5.2 创建模式对话框按照上面的方法,我们在对话框资源中添加控件资源,
并且按照修改对话框标题的方法对每个控件对 ID和
Caption进行修改,如表 5.1所示控件名称 ID值 Caption
Static Text
Edit Box
Group Box1
Radio Button1
Radio Button2
Group Box2
Combo Box
Group Box3
IDC_STATIC
IDC_EDIT_NAME
IDC_STATIC
IDC_RADIO_M
IDC_RADIO_F
IDC_STATIC
IDC_COMBO_SCHOO
LIDC_STATIC
姓名性别男女最高学历爱好返回 15
5.2 创建模式对话框步骤五,下面我们来设臵一下 Tab 键顺序 。 所谓 Tab 键顺序是指当对话框拥有输入焦点时,每次按下 Tab 键,对话框中各个控件依次拥有输入焦点的次序 。
选择 【 Layout】 菜单中的 【 Tab Order】 菜单项,或直接按下 Ctrl+D键,此时对话框中的每一个控件左上角将控件名称 ID值 Caption
Check Box1
Check Box2
Check Box3
Button1
Button2
IDC_CHECK_ART
IDC_CHECK_SPORT
IDC_CHECK_MCSIC
IDOK
IDCANCEL
艺术体育音乐确定取消返回 16
5.2 创建模式对话框会出现一个数字标签,这个数字标签就代表了 Tab 键顺序。
下面,我们按以下顺序,用鼠标左键单击每一个控件:
1,IDC_EDIT_NAME
2,IDC_RADIO_M
3,IDC_RADIO_F
4,IDC_COMBO_SCHOOL
5,IDC_CHECH_ART
6,IDC_CHECK_SPORT
7,IDC_CHECK-_MUSIC
8,IDOK
9,-IDCANCEL
返回 17
5.2 创建模式对话框按 【 Esc】 键退出设臵 Tab键顺序状态 。 并将以上各个控件的属性中的 【 Tab Stop】 复选框臵为选中状态 。
步骤六,测试生成对话框资源 。 选择 【 Dialog】 工具栏中的 【 Test】 按钮,或者直接按 Ctrl+T键,输入焦点应该首先在文本框 IDC_EDIT_NAME上,不断按 Tab键,观察输入焦点的变化是否和设臵的顺序一致 。 也可以进行在文本框中输入文本信息,选中单选按钮,选择组合框信息,
选中复选框等操作 。
5.2.3 创建对话框类
5.2.3.1创建对话框类并添加成员变量对话框资源已经编辑完成,下面的工作是通过 Class
Wizard 来创建自己的对话框类 。
返回 18
5.2 创建模式对话框步骤一,在对话框编辑器打开并且显示刚才新创建的对话框资源的情况下,选择 【 View】 菜单中的 【 Class
Wizard】 菜单项 。 Class Wizard会提示将对话框资源和一个类相连接,这个类可以是新创建的类,也可以是已经存在的类 。
步骤二,接受缺省设臵 【 Creat an new class】,单击
【 OK】 按钮,为对话框资源创建一个新类 。 系统将会弹出 【 New Class】 对话框 。
在 【 Name】 编辑框中输入需要生成的对话框类名
,CMydataDialog”,在指定对话框类名的同时,Class
Wizard将按照给出的对话框类名来自动定义生成的对话框的文件名为,MydataDialog.cpp” 。单击 【 OK】 按钮,
将继续执行。
返回 19
5.2 创建模式对话框步骤三,系统将返回 【 MFC Class Wizard】 对话框 。 选择
【 Member Variables】 选项卡来查看此对话框的成员变量表,可以通过此表将对话框中的不同的控件与相应的成员变量联系起来 。
在 【 Control IDs】 列表框中,选中 【 IDC_CHECK_ART】,
用鼠标单击 【 Add Variable】 按钮,系统将弹出一个用于添加成员变量的对话框 【 Add Member Variable】 。
在 【 Member variable name】 编辑框中输入变量的名称
,m_check_art”,这样就使成员变量,m_check_art” 和控件 【 IDC_CHECK_BOLD】 的数据之间建立了联系,通过定义的类成员变量就可以和控件的数据进行交互访问 。
由于复选框只有选中和未选中两种状态,因此我们将
【 Variable type】 定义为,BOOL” 值类型,当复选框选中时则成员变量 m_check_art 为 TRUE,否则为 FALSE。
返回 20
5.2 创建模式对话框按照表 5.2对其他成员变量进行设臵。设臵完成后单击
【 OK】 按钮退出。
在此要对单选按钮控件进行一下说明,因为它的处理方式与其他控件不同。此例中,我们使用了两个单选按钮,而且它们被定义为一组(通过选中 IDC_RADIO_M的
ID值 类成员变量
IDC_EDIT_NAME
IDC_RADIO_M
IDC_COMBO_SCHOOL
IDC_CHECK_ART
IDC_CHECK_SPORT
IDC_CHECK_MUSIC
m_edit_name
m_radio_m
m_combo_school
m_check_art
m_check_sport
m_check_music
返回 21
5.2 创建模式对话框
【 Properties】 对话框中的 【 Group】 复选框实现),
IDC_RADIO_M是组中的第一个按钮,在成员变表中,只有第一个按钮连接到一个整数类型的成员变量 — m_radio_m,
这个整数是基于零的索引,它可以表明这组中的哪一个按钮被选中。当,男,按钮被选中时,m_radio_m的值为 0;
当,女,按钮被选中时,m_radio_m值为 1。
另外,还要说明的一点是,当为控件 IDC-_EDIT_NAME
添加成员变量时,在 【 Member Variables】 选项卡的底部将出现一个编辑框 【 Maximum Characters】,我们可以在此处限制在编辑框 IDC-_EDIT_NAME中输入的字符串的最大长度 。
这样,对话框中的控件和对话框中的成员变量之间就建立了完全的对应关系,用这种方式生成的变量,系统会自动处理数据交换 。
返回 22
5.2 创建模式对话框
5.2.3.2 添加成员变量后的过程分析在对话框类中添加了成员变量后,应用程序 Dialog的源文件中增加了如下代码:
1,在头文件 MydataDialog.h中的 CMydataDialog类中,增加了映射变量的定义代码:
// Dialog Data
//{{AFX_DATA(CMydataDialog)
enum { IDD = IDD_DIALOG_Mydata };
BOOL m_check_art;
BOOL m_check_music;
BOOL m_check_sport;
Cstring m_combo_school;
Cstring m_edit_name;
返回 23
5.2 创建模式对话框
int m_radio_m;
//}}AFX_DATA
2,在实现文件 MydataDialog.cpp中的 CMydataDialog类的构造函数中,增加了变量的初始化代码:
CMydataDialog::CMydataDialog(CWnd *pParent
/*=NULL*/)
,CDialog(CMydataDialog::IDD,pParent)
{
//{{ AFX_DATA_INIT(CMydataDialog)
m_check_art = FALSE;
m_check_music = FALSE;
m_check_sport = FALSE;
返回 24
5.2 创建模式对话框
m_combo_school = _T("");
m_edit_name = _T("");
m_radio_m = -1;
//}}AFX_DATA_INIT
}
3,在实现文件 MydataDialog.cpp中的 DoDataExchange函数中,增加了对话框控制与对话框类的映射变量间的映射宏代码:
void CMydataDialog::DoDataExchange(CDataExchange* pDX)
{ CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMydataDialog)
返回 25
5.2 创建模式对话框
DDX_Check(pDX,IDC_CHECK_ART,m_check_art);
DDX_Check(pDX,IDC_CHECK_MUSIC,m_check_music);
DDX_Check(pDX,IDC_CHECK_SPORT,m_check_sport);
DDX_CBString(pDX,IDC_COMBO_SCHOOL,_combo_school);
DDX_Text(pDX,IDC_EDIT_NAME,m_edit_name);
DDX_Radio(pDX,IDC_RADIO_M,m_radio_m);
//}}AFX_DATA_MAP
}
5.2.3.3 Class Wizard识别和处理映射变量所需要的标识
Class Wizard通过固定的标识来实现对映射变量的管理 。
1,映射变量的定义映射变量必须定义在以下两行代码之间,才能被 Class
Wizard识别和处理,( 括号内为映射变量所属的类 )
返回 26
5.2 创建模式对话框
//{{AFX_DATA(CMydataDialog) //Class Wizard用来识
//别映射变量定义的起始代码
//}}AFX_DATA //Class Wizard用来识
//别映射变量定义的结束代码
2,映射变量的初始化映射变量的初始化代码必须放在在以下两行代码之间,
才能被 Class Wizard识别和处理:
//{{AFX_DATA_INIT(CMydataDialog) //Class Wizard用来识别映射变量初始化的起始代码
//}}AFX_DATA_INIT //Class Wizard用来识别映射变量初始化的结束代码返回 27
5.2 创建模式对话框
3,映射变量与对话框控制间的映射宏映射变量与控制间的映射宏代码必须放在在以下两行代码 ( 在函数 DoDataExchange()中 ) 之间,才能被 Class
Wizard识别和处理:
//{{AFX_DATA_MAP(CMydataDialog) //Class Wizard用来
//识别映射变量的映射宏的起始代码
//}}AFX_DATA_MAP //Class Wizard用来
//识别映射变量的映射宏的结束代码
5.2.4 对话框的实现一般情况下,用户是通过调用菜单项来激活对话框的,
在此,我们不妨先通过双击鼠标左键来激活对对话框的调用 。 具体步骤如下:
返回 28
5.2 创建模式对话框步骤一,选择 【 View】 菜单中的 【 Class Wizard】 菜单项,
弹出 【 MFC Class Wizard】 对话框,选择 【 Message Maps】
选项卡 。 在 【 Class name】 列表框中选择类 CdialogView,
在 【 Object IDs】 列表中选择 CdialogView,在对应的
【 Messages】 列表中选择 WM_LBUTTONDBLCLK。
步骤二,单击 【 Add Function】 按钮,添加对鼠标双击键的响应,在 【 Member Functions】 栏中,将会增加一个
OnLButtonDbClk函数 。
双击 OnLButtonDbClk函数,或者在选中此函数的情况下单击 【 Edit Code】 按钮,在出现的代码编辑窗口中输入以下程序代码 。 其中粗体部分为新输入的程序代码 。
返回 29
5.2 创建模式对话框
// CDialogView message handlers
void CDialogView::OnLButtonDblClk(UINT nFlags,CPoint point)
{// TODO,Add your message handler code here and/or call default
CMydataDialog dlg; //生成一个对话框类
//CMydataDialog的实例 dlg
dlg.m_radio_m=0; //对 dlg的成员变量 m_radio_m赋初值
dlg.m_edit_name=“” ;
CString msg;
if(dlg.DoModal()==IDOK) //调用成员函数 DoModal( )来显
//示对话框,并且等待用户的响应。
返回 30
5.2 创建模式对话框
{ msg=,<确定 >按钮被按下 !,; }
else
{ msg=,<取消 >按钮被按下 !,; }
msg+="\r\n\n";
msg+="姓 名,"; //输入姓名
msg+=dlg.m_edit_name;
msg+="\r\n";
msg+="性 别,"; //选择性别
switch(dlg.m_radio_m)
{
case 0:msg+="男 ";
break;
返回 31
5.2 创建模式对话框
case 1:msg+="女 ";
break;
}
msg+="\r\n";
msg+=,最高学历:,; //选择最高学历
msg+=dlg.m_combo_school;
msg+="\r\n";
msg+=,爱 好:,; //选择爱好
if(dlg.m_check_art==TRUE)
msg+="艺术 ";
if(dlg.m_check_music==TRUE)
msg+="音乐 ";
返回 32
5.2 创建模式对话框
if(dlg.m_check_sport==TRUE)
msg+="体育 ";
AfxMessageBox(msg); //最后调用 MFC类库
//中的全局函数 AfxMessageBox( ) 生成一个消息对话框,
//显示用户在对话框中的设臵
CView::OnLButtonDblClk(nFlags,point);
}
步骤三,在类 Cdialog View 的实现文件 Cdialog View.cpp
中加入对话框的头文件,其中粗体部分为新输入的程序代码 。
// DialogView.cpp,implementation of the CDialogView class
#include "stdafx.h"
#include "Dialog.h"
返回 33
5.2 创建模式对话框
#include "DialogDoc.h"
#include "DialogView.h"
#include "MydataDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
步骤四,选择 【 Build】 菜单中的 【 Build】 菜单项,或者直接单击 【 Build】 工具栏中的 【 Rebuild All】 按钮进行编译 。
返回 34
5.2 创建模式对话框步骤五,选择 【 Build】 菜单中 【 Execute】 菜单项,或者单击 【 Build】 工具栏中的 【 Execute Program】 运行程序 。
步骤六,在窗口中双击鼠标左键,弹出刚刚设计的,个人资料,对话框 。
可以在编辑框中输入姓名为,王春玲,,选择性别为
,女,,最高学历为,硕士,,爱好为,体育,和,音乐,,单击,确定,按钮退出时,将显示消息框如图所示。
返回 35
5.3 非模式对话框的实现非模式对话框的创建步骤基本上同模式对话框的创建一致,只是实现的原理不一样,在这里只介绍其独特的地方,其它共同部分可参照上一节中所介绍的步骤 。
模式和非模式对话框共享相同的基类 CDialog,并且它们都可以使用对话框编辑器来创建对话框资源 。
我们可以通过调用成员函数 DoModal( )来显示一个有模式的对话框,当函数返回时,对话框将不再存在。而无模式对话框在它本身处于激活状态时,还允许用户使用其他的应用程序。创建无模式对话框要比创建模式对话框复杂一些:首先要调用的默认构造函数构造一个对话框窗口对象;然后通过调用 CDialog的成员函数 Create
来创建对话框窗口,而不是调用成员函数 DoModal。并且当对话框仍然留在屏幕上时,控制已经立刻返回了。
返回 36
5.3 非模式对话框的实现下面,我们就来创建一个简单的非模式对话框,具体步骤如下:
步骤一,创建应用程序框架 。
利用 App Wizard在,E:\C++\Example\” 创建一个应用程序框架,Ndialog” 。 除了以下两个选项外,其他均使用默认值:选定 SingleDocument,并撤消 Printing And Print
Preview的选定 。
步骤二,创建对话框资源 。
1,选择 【 Insert】 菜单中的 【 Resource】 菜单项,然后选定
【 Dialog】 。
2,设臵对话框的标题为,非模式对话框,,ID值使用缺省值,IDD_DIALOG1” 。
3,添加两个控件:一个静态文本控件,标题为,输入信息,;一个编辑框控件 。 二者均使用默认 ID值 。
返回 37
5.3 非模式对话框的实现
4,在对话框属性的 【 More Styles】 中,选定 【 Visible】 属性。
步骤三,创建对话框类 CNDialog。
1,利用 Class Wizard创建对话框类 CNDialog。
2,为对象 IDOK和 IDCANCEL添加消息处理函数 。
(1) 在 【 Control IDs】 列表框中选择 IDOK,在 【 Messages】
列表框中选择 BN_CLICKED,单击 【 Add Function】 按钮,
出现 【 Add Member Function】 对话框,添加成员函数名为 OnOk;
(2) 在 【 Control IDs】 列表框中选择 IDCANCEL,在
【 Messages】 列表框中选择 BN_CLICKED,单击 【 Add
Function】 按钮,出现 【 Add Member Function】 对话框,
添加成员函数名为 OnCancel;
3,为控件 IDC_EDIT1添加成员变量:在 Class Wizard中单返回 38
5.3 非模式对话框的实现击 【 Member Variables】 选项卡,选择 IDC_EDIT1控件,
单击 【 Add Variable】 按钮,添加成员变量 m_strEdit1。
4,在 NDialog.h文件中添加如下代码,其中粗体为新添加的代码:
// CNDialog dialog
class CNDialog,public CDialog
{// Construction
public:
CNDialog(CWnd* pParent = NULL);// standard constructor
CNDialog(CView*pView); // 函数原型
BOOL Create();
返回 39
5.3 非模式对话框的实现
public,//视图指针
CView*m_pView;
// Dialog Data
5,在 NDialog.cpp文件中添加如下代码,其中粗体为新添加的代码:
( 1) 增加非模式构造函数:
CNDialog::CNDialog(CWnd* pParent /*=NULL*/)
,CDialog(CNDialog::IDD,pParent)
{ //{{AFX_DATA_INIT(CNDialog)
m_strEdit1 = _T("");
//}}AFX_DATA_INIT
m_pView=NULL;
}
返回 40
5.3 非模式对话框的实现
CNDialog::CNDialog(CView*pView)
{ m_pView=pView; }
( 2) 添加 Create函数:
BOOL CNDialog::Create()
{ return CDialog::Create(CNDialog::IDD); }
void CNDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CNDialog)
DDX_Text(pDX,IDC_EDIT1,m_strEdit1);
//}}AFX_DATA_MAP
}
返回 41
5.3 非模式对话框的实现
( 3) 编辑 OnOk和 OnCancel函数:
void CNDialog::OnOK()
{ // TODO,Add extra validation here
if(m_pView!=NULL)
{
UpdateData(TRUE);
m_pView->PostMessage(WM_GOOD,IDOK);
}
else
{ CDialog::OnOK(); }
}
返回 42
5.3 非模式对话框的实现
void CNDialog::OnCancel()
{
// TODO,Add extra cleanup here
if(m_pView!=NULL)
{m_pView-PostMessage(WM_GOOD,IDCANCEL);
}
else
{CDialog::OnCancel();
}
}
6,在 NDialogView.h文件中添加如下代码,其中粗体为新添加的代码:
返回 43
5.3 非模式对话框的实现
public:
CNDialogDoc* GetDocument();
CNDialog*m_pDlg; //定义一个数据成员来存放对话
//框指针
7,在 NDialogView.cpp文件中添加如下代码,其中粗体为新添加的代码:
// CNDialogView construction/destruction
CNDialogView::CNDialogView( )
//修改 CNDialogView的构造函数和析构函数
{ // TODO,add construction code here
m_pDlg=new CNDialog( ); }
CNDialogView::~CNDialogView( )
{ delete m_pDlg; }
返回 44
5.3 非模式对话框的实现步骤四,非模式对话框的实现 。
1,在 NDialogView.cpp文件中为函数 OnDraw( ) 添加如下代码,其中粗体为新添加的代码:
void CNDialogView::OnDraw(CDC* pDC)
{ CNDialogDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO,add draw code for native data here
pDC->TextOut(0,0,"Press the left mouse button here.");
//提示用户按下鼠标左键
}
2,添加鼠标消息处理函数 。
( 1) 选择 【 View】 菜单中的 【 Class Wizard】 菜单项,弹出 【 MFC Class Wizard】 对话框,选择 【 Message Maps】
返回 45
5.3 非模式对话框的实现选项卡 。 在 【 Class name】 列表框中选择类 CdialogView,
在 【 Object IDs】 列表 中选择 CdialogView,在对 应的
【 Messages】 列表中选择 WM_LBUTTONDOWN。
( 2) 单击 【 Add Function】 按钮,添加对鼠标双击键的响应,
在 【 Member Functions】 栏中,将 会 增 加 一 个
OnLButtonDown函数 。
( 3) 双击 OnLButtonDown函数,或者在选中此函数的情况下单击 【 Edit Code】 按钮,在出现的代码编辑窗口中输入以下程序代码 。 其中粗体部分为新输入的程序代码 。
void CNDialogView::OnLButtonDown(UINT nFlags,CPoint point)
{
// TODO,Add your message handler code here and/or call default
返回 46
5.3 非模式对话框的实现
if(m_pDlg->GetSafeHwnd()==0)
{ m_pDlg->Create(); } //显示对话框窗口
CView::OnLButtonDown(nFlags,point);
}
( 4 ) 用同样方法为鼠标右键建立消息处理函数
OnRButtonDown,并添加如下代码:
void CNDialogView::OnRButtonDown(UINT nFlags,CPoint
point)
{// TODO,Add your message handler code here and/or call
default
m_pDlg->DestroyWindow();
CView::OnRButtonDown(nFlags,point);
}
返回 47
5.3 非模式对话框的实现
3,增加自己的消息代码 。
( 1) 在 NDialog.h文件中定义 WM_GOOD消息 ID,其中粗体为新添加的代码:
#include "resource.h" // main symbols
#define WM_GOOD WM_USER+5
( 2 ) 在 NDialogView.cpp 文 件 中 添 加 如 下 代 码,
BEGIN_MESSAGE_MAP(CNDialogView,CView)
ON_MESSAGE(WM_GOOD,OnGood)
//{{AFX_MSG_MAP(CNDialogView)
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
返回 48
5.3 非模式对话框的实现
( 3) 在 NDialogView.cpp文件中增加消息处理函数,其中粗体为新添加的代码:
// CNDialogView message handlers
LRESULT CNDialogView::OnGood(WPARAM
wParam,LPARAM lParam)
{ TRACE("CNDialogView::OnGood%x,%1X\n",
wParam,lParam);
(const char*)m_pDlg->m_strEdit1;
m_pDlg->DestroyWindow();
return 0;
}
返回 49
5.3 非模式对话框的实现
( 4) 在 NDialogView.h文件中增加如下函数原型,其中粗体为新添加的代码:
// Generated message map functions
protected:
//{{AFX_MSG(CNDialogView)
afx_msg void OnLButtonDown(UINT nFlags,CPoint point);
afx_msg void OnRButtonDown(UINT nFlags,CPoint point);
//}}AFX_MSG
afx_msg LRESULT OnGood(WPARAM wParam,
LPARAM lParam);
DECLARE_MESSAGE_MAP() };
返回 50
5.3 非模式对话框的实现
4,在 NDialogView,cpp文件中添加头文件包含语句,其中粗体为新添加的代码:
#include "NDialogDoc.h"
#include "NDialogView.h"
#include "NDialog.h"
5,运行并测试应用程序 。
( 1) 编译并运行应用程序 Ndialog。
( 2) 按下鼠标左键,则,非模式对话框,出现 。
( 3) 在对话框外的区域,按下鼠标右键,则,非模式对话框,消失 。
( 4) 再次按下鼠标左键,则,非模式对话框,又出现 。
( 5) 在编辑框中输入内容,单击 【 OK】 按钮,则对话框关闭 。
返回 51
5.3 非模式对话框的实现
5.4 创建对话框的主要步骤要创建一个完整的对话框必须经过两个步骤:一是用资源编辑器创建对话框资源,二是用 Class Wizard来创建对话框类 。 无论是模式对话框还是无模式对话框,这两个步骤都是一样的 。 创建对话框的主要步骤如下:
步骤零,先创建一个应用程序框架 。
步骤一,在已经打开的工程文件中,利用资源编辑器来设计一个含有各种控制件的对话框资源;
步骤二,利用 Class Wizard来创建对话框类,它是由
CDialog类派生的;
步骤三,将对话框资源中的控件与对话框类中的消息处理函数连接起来;
返回 52
5.3 非模式对话框的实现步骤四,利用 Class Wizard添加与对话框控件有关的成员变量,数据交换函数及数据确认函数;
步 骤 五,对 一 些 特 殊 的 控 制 初 始 化 函 数 ( 如
OnIntiaDialog( )) 及消息控制函数进行编辑;
步骤六,把对话框与具体的菜单命令相联系 。
返回 53
本章小结返回 54
习题
第五章 对话框及常用控件本章导读在 Windows应用程序中,对话框 ( Dialog) 是最重要的用户界面元素之一,是应用程序与用户交互的重要手段 。 当用户进行某项操作之后,弹出一个对话框把反馈信息传递给用户,也可以要求用户输入数据或者进行选择 。
控件在 Windows应用程序中也很常见 。 一般来说,
在对话框中是通过各种控件来和用户进行交互的,我们经常用到的控件有按钮,列表框,编辑框,组合框,
滚动条等 。 实际上,控件是一种特殊类型的窗口,通常为其父窗口所拥有 。
返回 2
5.1 对话框的组成和分类
5.1.1 对话框的组成在 Visual C++中,对话框主要是由对话框资源和对话框类组成:
1,对话框资源对话框资源中描述的是对话框的大小,风格等特性,
以及对话框中控件的类型和它们的位臵 。 定义对话框资源最简单,最有效的方法就是使用 Visual C++中的资源编辑器 。
2,对话框类对话框资源所提供的仅仅是一个数据结构,要利用所创建的对话框资源,必须要创建以它作为资源的对话框类,对话框类是从 CDialog类中派生出的子类,它提供了编程接口来管理对话框 。
返回 3
5.1 对话框的组成和分类
5.1.2 对话框的分类对话框有两种类型:模式对话框和无模式对话框 。 下面分别对这两种对话框进行说明 。
1,模式对话框所谓,模式对话框,是指对话框被弹出后,用户必须在对话框中作出相应的操作;在退出对话框之前,会阻止其他应用程序的运行 ( 包括它所在的应用程序 ) 。
一般情况下,模式对话框会有 【 OK】 ( 确定 ) 和
【 Cancel】 ( 取消 ) 两个按钮 。 单击 【 OK】 按钮,系统认定用户在对话框中的选择或输入有效,退出对话框;
单击 【 Cancel】 按钮,系统认定用户在对话框中的选择或输入无效,退出对话框,程序恢复原有状态 。
返回 4
5.1 对话框的组成和分类
2,无模式对话框所谓,无模式对话框,是指当对话框被弹出后,将一直保留在屏幕上,但不影响其他应用程序的运行,用户可以继续在对话框所在的应用程序中进行其他操作;
当需要使用对话框时,只需像激活一般窗口一样单击对话框所在的区域即可。例如在 Microsoft Word中的,查找,和,替换,对话框。
两种对话框在用资源编辑器设计和使用 Class Wizard
进行编程时的方法基本一致 。 但在创建和退出窗口时的方式有所不同 。
返回 5
5.1 对话框的组成和分类
1,在创建时,模式对话框是由系统自动分配内存空间,
因此在退出对话框时,对话框对象会自动删除 。 而无模式对话框则是需要用户来指定内存,退出时还需用户自己来删除对话框对象 。
2,在退出时,两种对话框所使用的终止函数不一样 。
模式对话框通过调用 CDialog::EndDialog来终止,而无模式对话框则是通过调用 CWnd::DestroyWindow
来终止 。
返回 6
5.2 创建模式对话框
5.2.1 创建应用程序框架在进行创建对话框之前,我们首先按照第四章介绍的方法创建一个应用程序框架,并且在 Visual C++ 6.0中将
,工程,打开 。
步骤一,在 Visual C++ 6.0中选择 【 File】 菜单的 【 New】
菜单命令,弹出 【 new】 对话框 。 在工程列表中选中选项
【 MFC AppWizard[exe]】,在 【 Project name】 栏中输入工程名称为 【 Dialog】,在 【 Location】 栏中指定工程的存储路径为 E:\C++\EXAMPLE\。 单击 【 OK】 按钮启动 App
Wizard。
步骤二,在接下来的 AppWizard的各个步骤中按下列要求设臵选项:
返回 7
5.2 创建模式对话框
Step 1,选择单文档界面 ( Single Document),其他接受系统缺省设臵,单击 【 Next】 按钮,进入下一步 。
Step 2,接受系统缺省设臵,单击 【 Next】 按钮
Step 3,关闭 【 ActiveX Controls】 复选框选项,单击 Next】
按钮,进入下一步 。
Step 4,关闭 【 Docking toolbar】,【 Initial status bar】,
【 Printing and print preview】,以及 【 3D Control】 复选框选项,单击 【 Next】 按钮,进入下一步 。
Step 5,接受系统缺省设臵,单击 【 Next】 按钮 。
Step 6,接受系统缺省设臵,单击 【 Finish】 按钮 。
最后,弹出工程信息对话框,单击 【 OK】 按钮,完成应用程序框架的设计 。
返回 8
5.2 创建模式对话框
5.2.2 创建对话框资源接下来,我们要做的工作是创建对话框资源,其创建步骤如下:
步骤一,在打开的工程中,选择 【 Insert】 菜单中的
【 Resource】 菜单项,或直接按 Ctrl+R键,系统将弹出
【 Insert Resource】 对话框步骤二,在对话框中选择 【 Dialog】 选项,然后单击
【 New】 按钮,或直接双击 【 Dialog】 选项,这时对话框资源编辑器将显示在 Visual C++平台中,在对话框资源编辑器中显示了一个只有 【 OK】 按钮和 【 Cancel】 按钮的简单的对话框。
返回 9
5.2 创建模式对话框在新建对话框的同时,在其右边随之出现了一个控件模板,即 Controls工具栏,它的作用是向对话框资源中添加控件。工具栏中的每一个图标(除了左上角的指针)
都代表一种能够添加到对话框中的控件,我们可以用一种,所见即所得,的方式来向对话框资源添加各种控件。
如果仔细观察一下系统的菜单,你就会发现菜单中多了一项 【 Layout】 菜单,而且在状态拦的上面增加了一个新的工具栏 —— 【 Dialog】 工具栏,其中的按钮在编辑对话框资源和增加控件时是十分有用的工具。下面我们对
【 Dialog】 工具栏进行详细的说明。
返回 10
5.2 创建模式对话框
1,Test:单独运行对话框来测试对话框的外观和行为;
2,Align Left,将选定的多个控件按照左对齐的格式放臵;
3,lign Right:将选定的多个控件按照右对齐的格式放臵
4,Align Top:将选定的多个控件按照上对齐的格式放臵
5,Align Botton:将选定的多个控件按照下对齐格式放臵
6,Central Vertical:将选定的一个或多个控件按照中心垂直对齐格式放臵
7,Central Horizontal,将选定的一个或多个控件按照中心水平对齐格式放臵
8,Space Across:将选定的多个控件两两之间的水平间隔相同返回 11
5.2 创建模式对话框
9,Space Down:将选定的多个控件两两之间的垂直间隔相同
10,Make Same Width:使选定的多个控件具有相同的宽度,
宽度的标准是最后选择的控件
11,Make Same Height:使选定的多个控件具有相同的高度,
高度的标准是最后选择的控件
12,Make Same Size:使选定的多个控件具有相同的高度和宽度,高度和宽度的标准是最后选择的控件
13,Toggle Grid:显示或隐藏网格
14,Toggle Guides:显示或隐藏标尺返回 12
5.2 创建模式对话框步骤三,系统默认产生的对话框的标题是,Dialog”,下面我们来更改一下对话框的标题 。
选择 【 View】 菜单下的 【 Properties】 菜单项,或对话框窗体上单击鼠标右键,在弹出的快捷菜单中选
【 properties】 菜单项,系统将弹出对话框资源的属性对话框 。 选择 【 General】 选项卡,在其中的 【 Caption】
框中输入对话框标题的名称为,个人资料,。 资源 【 ID】
框中的默认值为 IDD-DIALOG1,可以按照自己的需要修改为便个于记忆的标识符 。 因为此对话框的内容主要用于显示人资料,所以在此示例中,我们将 【 ID】 改为
,IDD_DIALOG_M ydata” 。 按,回车,键,完成对话框标题和 ID的更改 。
返回 13
5.2 创建模式对话框在 Visual C++中,对于不同的控件定义了不同的 ID 类型,IDC_是控件的 ID 值 (ID of Control) 的前缀; IDD_
是对话框的 ID值 ( ID of Dialog) 的前缀; ID是系统自己缺省的 ID值的前缀 。
步骤四,向对话框中添加控件 。 向对话框中添加控件的方法有两种:
1,在控件工具栏中选择所需要的控件,按下鼠标的左键
( 不要松开 ),将鼠标拖到对话框中松开,在对话框中将添加一个指定的控件 。
2,在控件工具栏中单击所需要的控件,此时控件将呈凹下状态,将鼠标移至对话框,鼠标此时显示为,十,字形,按下鼠标左键,在对话框上拖动至适当大小,松开鼠标左键,开鼠标左键,在对话框中将添加一个指定的控件 。
返回 14
5.2 创建模式对话框按照上面的方法,我们在对话框资源中添加控件资源,
并且按照修改对话框标题的方法对每个控件对 ID和
Caption进行修改,如表 5.1所示控件名称 ID值 Caption
Static Text
Edit Box
Group Box1
Radio Button1
Radio Button2
Group Box2
Combo Box
Group Box3
IDC_STATIC
IDC_EDIT_NAME
IDC_STATIC
IDC_RADIO_M
IDC_RADIO_F
IDC_STATIC
IDC_COMBO_SCHOO
LIDC_STATIC
姓名性别男女最高学历爱好返回 15
5.2 创建模式对话框步骤五,下面我们来设臵一下 Tab 键顺序 。 所谓 Tab 键顺序是指当对话框拥有输入焦点时,每次按下 Tab 键,对话框中各个控件依次拥有输入焦点的次序 。
选择 【 Layout】 菜单中的 【 Tab Order】 菜单项,或直接按下 Ctrl+D键,此时对话框中的每一个控件左上角将控件名称 ID值 Caption
Check Box1
Check Box2
Check Box3
Button1
Button2
IDC_CHECK_ART
IDC_CHECK_SPORT
IDC_CHECK_MCSIC
IDOK
IDCANCEL
艺术体育音乐确定取消返回 16
5.2 创建模式对话框会出现一个数字标签,这个数字标签就代表了 Tab 键顺序。
下面,我们按以下顺序,用鼠标左键单击每一个控件:
1,IDC_EDIT_NAME
2,IDC_RADIO_M
3,IDC_RADIO_F
4,IDC_COMBO_SCHOOL
5,IDC_CHECH_ART
6,IDC_CHECK_SPORT
7,IDC_CHECK-_MUSIC
8,IDOK
9,-IDCANCEL
返回 17
5.2 创建模式对话框按 【 Esc】 键退出设臵 Tab键顺序状态 。 并将以上各个控件的属性中的 【 Tab Stop】 复选框臵为选中状态 。
步骤六,测试生成对话框资源 。 选择 【 Dialog】 工具栏中的 【 Test】 按钮,或者直接按 Ctrl+T键,输入焦点应该首先在文本框 IDC_EDIT_NAME上,不断按 Tab键,观察输入焦点的变化是否和设臵的顺序一致 。 也可以进行在文本框中输入文本信息,选中单选按钮,选择组合框信息,
选中复选框等操作 。
5.2.3 创建对话框类
5.2.3.1创建对话框类并添加成员变量对话框资源已经编辑完成,下面的工作是通过 Class
Wizard 来创建自己的对话框类 。
返回 18
5.2 创建模式对话框步骤一,在对话框编辑器打开并且显示刚才新创建的对话框资源的情况下,选择 【 View】 菜单中的 【 Class
Wizard】 菜单项 。 Class Wizard会提示将对话框资源和一个类相连接,这个类可以是新创建的类,也可以是已经存在的类 。
步骤二,接受缺省设臵 【 Creat an new class】,单击
【 OK】 按钮,为对话框资源创建一个新类 。 系统将会弹出 【 New Class】 对话框 。
在 【 Name】 编辑框中输入需要生成的对话框类名
,CMydataDialog”,在指定对话框类名的同时,Class
Wizard将按照给出的对话框类名来自动定义生成的对话框的文件名为,MydataDialog.cpp” 。单击 【 OK】 按钮,
将继续执行。
返回 19
5.2 创建模式对话框步骤三,系统将返回 【 MFC Class Wizard】 对话框 。 选择
【 Member Variables】 选项卡来查看此对话框的成员变量表,可以通过此表将对话框中的不同的控件与相应的成员变量联系起来 。
在 【 Control IDs】 列表框中,选中 【 IDC_CHECK_ART】,
用鼠标单击 【 Add Variable】 按钮,系统将弹出一个用于添加成员变量的对话框 【 Add Member Variable】 。
在 【 Member variable name】 编辑框中输入变量的名称
,m_check_art”,这样就使成员变量,m_check_art” 和控件 【 IDC_CHECK_BOLD】 的数据之间建立了联系,通过定义的类成员变量就可以和控件的数据进行交互访问 。
由于复选框只有选中和未选中两种状态,因此我们将
【 Variable type】 定义为,BOOL” 值类型,当复选框选中时则成员变量 m_check_art 为 TRUE,否则为 FALSE。
返回 20
5.2 创建模式对话框按照表 5.2对其他成员变量进行设臵。设臵完成后单击
【 OK】 按钮退出。
在此要对单选按钮控件进行一下说明,因为它的处理方式与其他控件不同。此例中,我们使用了两个单选按钮,而且它们被定义为一组(通过选中 IDC_RADIO_M的
ID值 类成员变量
IDC_EDIT_NAME
IDC_RADIO_M
IDC_COMBO_SCHOOL
IDC_CHECK_ART
IDC_CHECK_SPORT
IDC_CHECK_MUSIC
m_edit_name
m_radio_m
m_combo_school
m_check_art
m_check_sport
m_check_music
返回 21
5.2 创建模式对话框
【 Properties】 对话框中的 【 Group】 复选框实现),
IDC_RADIO_M是组中的第一个按钮,在成员变表中,只有第一个按钮连接到一个整数类型的成员变量 — m_radio_m,
这个整数是基于零的索引,它可以表明这组中的哪一个按钮被选中。当,男,按钮被选中时,m_radio_m的值为 0;
当,女,按钮被选中时,m_radio_m值为 1。
另外,还要说明的一点是,当为控件 IDC-_EDIT_NAME
添加成员变量时,在 【 Member Variables】 选项卡的底部将出现一个编辑框 【 Maximum Characters】,我们可以在此处限制在编辑框 IDC-_EDIT_NAME中输入的字符串的最大长度 。
这样,对话框中的控件和对话框中的成员变量之间就建立了完全的对应关系,用这种方式生成的变量,系统会自动处理数据交换 。
返回 22
5.2 创建模式对话框
5.2.3.2 添加成员变量后的过程分析在对话框类中添加了成员变量后,应用程序 Dialog的源文件中增加了如下代码:
1,在头文件 MydataDialog.h中的 CMydataDialog类中,增加了映射变量的定义代码:
// Dialog Data
//{{AFX_DATA(CMydataDialog)
enum { IDD = IDD_DIALOG_Mydata };
BOOL m_check_art;
BOOL m_check_music;
BOOL m_check_sport;
Cstring m_combo_school;
Cstring m_edit_name;
返回 23
5.2 创建模式对话框
int m_radio_m;
//}}AFX_DATA
2,在实现文件 MydataDialog.cpp中的 CMydataDialog类的构造函数中,增加了变量的初始化代码:
CMydataDialog::CMydataDialog(CWnd *pParent
/*=NULL*/)
,CDialog(CMydataDialog::IDD,pParent)
{
//{{ AFX_DATA_INIT(CMydataDialog)
m_check_art = FALSE;
m_check_music = FALSE;
m_check_sport = FALSE;
返回 24
5.2 创建模式对话框
m_combo_school = _T("");
m_edit_name = _T("");
m_radio_m = -1;
//}}AFX_DATA_INIT
}
3,在实现文件 MydataDialog.cpp中的 DoDataExchange函数中,增加了对话框控制与对话框类的映射变量间的映射宏代码:
void CMydataDialog::DoDataExchange(CDataExchange* pDX)
{ CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMydataDialog)
返回 25
5.2 创建模式对话框
DDX_Check(pDX,IDC_CHECK_ART,m_check_art);
DDX_Check(pDX,IDC_CHECK_MUSIC,m_check_music);
DDX_Check(pDX,IDC_CHECK_SPORT,m_check_sport);
DDX_CBString(pDX,IDC_COMBO_SCHOOL,_combo_school);
DDX_Text(pDX,IDC_EDIT_NAME,m_edit_name);
DDX_Radio(pDX,IDC_RADIO_M,m_radio_m);
//}}AFX_DATA_MAP
}
5.2.3.3 Class Wizard识别和处理映射变量所需要的标识
Class Wizard通过固定的标识来实现对映射变量的管理 。
1,映射变量的定义映射变量必须定义在以下两行代码之间,才能被 Class
Wizard识别和处理,( 括号内为映射变量所属的类 )
返回 26
5.2 创建模式对话框
//{{AFX_DATA(CMydataDialog) //Class Wizard用来识
//别映射变量定义的起始代码
//}}AFX_DATA //Class Wizard用来识
//别映射变量定义的结束代码
2,映射变量的初始化映射变量的初始化代码必须放在在以下两行代码之间,
才能被 Class Wizard识别和处理:
//{{AFX_DATA_INIT(CMydataDialog) //Class Wizard用来识别映射变量初始化的起始代码
//}}AFX_DATA_INIT //Class Wizard用来识别映射变量初始化的结束代码返回 27
5.2 创建模式对话框
3,映射变量与对话框控制间的映射宏映射变量与控制间的映射宏代码必须放在在以下两行代码 ( 在函数 DoDataExchange()中 ) 之间,才能被 Class
Wizard识别和处理:
//{{AFX_DATA_MAP(CMydataDialog) //Class Wizard用来
//识别映射变量的映射宏的起始代码
//}}AFX_DATA_MAP //Class Wizard用来
//识别映射变量的映射宏的结束代码
5.2.4 对话框的实现一般情况下,用户是通过调用菜单项来激活对话框的,
在此,我们不妨先通过双击鼠标左键来激活对对话框的调用 。 具体步骤如下:
返回 28
5.2 创建模式对话框步骤一,选择 【 View】 菜单中的 【 Class Wizard】 菜单项,
弹出 【 MFC Class Wizard】 对话框,选择 【 Message Maps】
选项卡 。 在 【 Class name】 列表框中选择类 CdialogView,
在 【 Object IDs】 列表中选择 CdialogView,在对应的
【 Messages】 列表中选择 WM_LBUTTONDBLCLK。
步骤二,单击 【 Add Function】 按钮,添加对鼠标双击键的响应,在 【 Member Functions】 栏中,将会增加一个
OnLButtonDbClk函数 。
双击 OnLButtonDbClk函数,或者在选中此函数的情况下单击 【 Edit Code】 按钮,在出现的代码编辑窗口中输入以下程序代码 。 其中粗体部分为新输入的程序代码 。
返回 29
5.2 创建模式对话框
// CDialogView message handlers
void CDialogView::OnLButtonDblClk(UINT nFlags,CPoint point)
{// TODO,Add your message handler code here and/or call default
CMydataDialog dlg; //生成一个对话框类
//CMydataDialog的实例 dlg
dlg.m_radio_m=0; //对 dlg的成员变量 m_radio_m赋初值
dlg.m_edit_name=“” ;
CString msg;
if(dlg.DoModal()==IDOK) //调用成员函数 DoModal( )来显
//示对话框,并且等待用户的响应。
返回 30
5.2 创建模式对话框
{ msg=,<确定 >按钮被按下 !,; }
else
{ msg=,<取消 >按钮被按下 !,; }
msg+="\r\n\n";
msg+="姓 名,"; //输入姓名
msg+=dlg.m_edit_name;
msg+="\r\n";
msg+="性 别,"; //选择性别
switch(dlg.m_radio_m)
{
case 0:msg+="男 ";
break;
返回 31
5.2 创建模式对话框
case 1:msg+="女 ";
break;
}
msg+="\r\n";
msg+=,最高学历:,; //选择最高学历
msg+=dlg.m_combo_school;
msg+="\r\n";
msg+=,爱 好:,; //选择爱好
if(dlg.m_check_art==TRUE)
msg+="艺术 ";
if(dlg.m_check_music==TRUE)
msg+="音乐 ";
返回 32
5.2 创建模式对话框
if(dlg.m_check_sport==TRUE)
msg+="体育 ";
AfxMessageBox(msg); //最后调用 MFC类库
//中的全局函数 AfxMessageBox( ) 生成一个消息对话框,
//显示用户在对话框中的设臵
CView::OnLButtonDblClk(nFlags,point);
}
步骤三,在类 Cdialog View 的实现文件 Cdialog View.cpp
中加入对话框的头文件,其中粗体部分为新输入的程序代码 。
// DialogView.cpp,implementation of the CDialogView class
#include "stdafx.h"
#include "Dialog.h"
返回 33
5.2 创建模式对话框
#include "DialogDoc.h"
#include "DialogView.h"
#include "MydataDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
步骤四,选择 【 Build】 菜单中的 【 Build】 菜单项,或者直接单击 【 Build】 工具栏中的 【 Rebuild All】 按钮进行编译 。
返回 34
5.2 创建模式对话框步骤五,选择 【 Build】 菜单中 【 Execute】 菜单项,或者单击 【 Build】 工具栏中的 【 Execute Program】 运行程序 。
步骤六,在窗口中双击鼠标左键,弹出刚刚设计的,个人资料,对话框 。
可以在编辑框中输入姓名为,王春玲,,选择性别为
,女,,最高学历为,硕士,,爱好为,体育,和,音乐,,单击,确定,按钮退出时,将显示消息框如图所示。
返回 35
5.3 非模式对话框的实现非模式对话框的创建步骤基本上同模式对话框的创建一致,只是实现的原理不一样,在这里只介绍其独特的地方,其它共同部分可参照上一节中所介绍的步骤 。
模式和非模式对话框共享相同的基类 CDialog,并且它们都可以使用对话框编辑器来创建对话框资源 。
我们可以通过调用成员函数 DoModal( )来显示一个有模式的对话框,当函数返回时,对话框将不再存在。而无模式对话框在它本身处于激活状态时,还允许用户使用其他的应用程序。创建无模式对话框要比创建模式对话框复杂一些:首先要调用的默认构造函数构造一个对话框窗口对象;然后通过调用 CDialog的成员函数 Create
来创建对话框窗口,而不是调用成员函数 DoModal。并且当对话框仍然留在屏幕上时,控制已经立刻返回了。
返回 36
5.3 非模式对话框的实现下面,我们就来创建一个简单的非模式对话框,具体步骤如下:
步骤一,创建应用程序框架 。
利用 App Wizard在,E:\C++\Example\” 创建一个应用程序框架,Ndialog” 。 除了以下两个选项外,其他均使用默认值:选定 SingleDocument,并撤消 Printing And Print
Preview的选定 。
步骤二,创建对话框资源 。
1,选择 【 Insert】 菜单中的 【 Resource】 菜单项,然后选定
【 Dialog】 。
2,设臵对话框的标题为,非模式对话框,,ID值使用缺省值,IDD_DIALOG1” 。
3,添加两个控件:一个静态文本控件,标题为,输入信息,;一个编辑框控件 。 二者均使用默认 ID值 。
返回 37
5.3 非模式对话框的实现
4,在对话框属性的 【 More Styles】 中,选定 【 Visible】 属性。
步骤三,创建对话框类 CNDialog。
1,利用 Class Wizard创建对话框类 CNDialog。
2,为对象 IDOK和 IDCANCEL添加消息处理函数 。
(1) 在 【 Control IDs】 列表框中选择 IDOK,在 【 Messages】
列表框中选择 BN_CLICKED,单击 【 Add Function】 按钮,
出现 【 Add Member Function】 对话框,添加成员函数名为 OnOk;
(2) 在 【 Control IDs】 列表框中选择 IDCANCEL,在
【 Messages】 列表框中选择 BN_CLICKED,单击 【 Add
Function】 按钮,出现 【 Add Member Function】 对话框,
添加成员函数名为 OnCancel;
3,为控件 IDC_EDIT1添加成员变量:在 Class Wizard中单返回 38
5.3 非模式对话框的实现击 【 Member Variables】 选项卡,选择 IDC_EDIT1控件,
单击 【 Add Variable】 按钮,添加成员变量 m_strEdit1。
4,在 NDialog.h文件中添加如下代码,其中粗体为新添加的代码:
// CNDialog dialog
class CNDialog,public CDialog
{// Construction
public:
CNDialog(CWnd* pParent = NULL);// standard constructor
CNDialog(CView*pView); // 函数原型
BOOL Create();
返回 39
5.3 非模式对话框的实现
public,//视图指针
CView*m_pView;
// Dialog Data
5,在 NDialog.cpp文件中添加如下代码,其中粗体为新添加的代码:
( 1) 增加非模式构造函数:
CNDialog::CNDialog(CWnd* pParent /*=NULL*/)
,CDialog(CNDialog::IDD,pParent)
{ //{{AFX_DATA_INIT(CNDialog)
m_strEdit1 = _T("");
//}}AFX_DATA_INIT
m_pView=NULL;
}
返回 40
5.3 非模式对话框的实现
CNDialog::CNDialog(CView*pView)
{ m_pView=pView; }
( 2) 添加 Create函数:
BOOL CNDialog::Create()
{ return CDialog::Create(CNDialog::IDD); }
void CNDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CNDialog)
DDX_Text(pDX,IDC_EDIT1,m_strEdit1);
//}}AFX_DATA_MAP
}
返回 41
5.3 非模式对话框的实现
( 3) 编辑 OnOk和 OnCancel函数:
void CNDialog::OnOK()
{ // TODO,Add extra validation here
if(m_pView!=NULL)
{
UpdateData(TRUE);
m_pView->PostMessage(WM_GOOD,IDOK);
}
else
{ CDialog::OnOK(); }
}
返回 42
5.3 非模式对话框的实现
void CNDialog::OnCancel()
{
// TODO,Add extra cleanup here
if(m_pView!=NULL)
{m_pView-PostMessage(WM_GOOD,IDCANCEL);
}
else
{CDialog::OnCancel();
}
}
6,在 NDialogView.h文件中添加如下代码,其中粗体为新添加的代码:
返回 43
5.3 非模式对话框的实现
public:
CNDialogDoc* GetDocument();
CNDialog*m_pDlg; //定义一个数据成员来存放对话
//框指针
7,在 NDialogView.cpp文件中添加如下代码,其中粗体为新添加的代码:
// CNDialogView construction/destruction
CNDialogView::CNDialogView( )
//修改 CNDialogView的构造函数和析构函数
{ // TODO,add construction code here
m_pDlg=new CNDialog( ); }
CNDialogView::~CNDialogView( )
{ delete m_pDlg; }
返回 44
5.3 非模式对话框的实现步骤四,非模式对话框的实现 。
1,在 NDialogView.cpp文件中为函数 OnDraw( ) 添加如下代码,其中粗体为新添加的代码:
void CNDialogView::OnDraw(CDC* pDC)
{ CNDialogDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO,add draw code for native data here
pDC->TextOut(0,0,"Press the left mouse button here.");
//提示用户按下鼠标左键
}
2,添加鼠标消息处理函数 。
( 1) 选择 【 View】 菜单中的 【 Class Wizard】 菜单项,弹出 【 MFC Class Wizard】 对话框,选择 【 Message Maps】
返回 45
5.3 非模式对话框的实现选项卡 。 在 【 Class name】 列表框中选择类 CdialogView,
在 【 Object IDs】 列表 中选择 CdialogView,在对 应的
【 Messages】 列表中选择 WM_LBUTTONDOWN。
( 2) 单击 【 Add Function】 按钮,添加对鼠标双击键的响应,
在 【 Member Functions】 栏中,将 会 增 加 一 个
OnLButtonDown函数 。
( 3) 双击 OnLButtonDown函数,或者在选中此函数的情况下单击 【 Edit Code】 按钮,在出现的代码编辑窗口中输入以下程序代码 。 其中粗体部分为新输入的程序代码 。
void CNDialogView::OnLButtonDown(UINT nFlags,CPoint point)
{
// TODO,Add your message handler code here and/or call default
返回 46
5.3 非模式对话框的实现
if(m_pDlg->GetSafeHwnd()==0)
{ m_pDlg->Create(); } //显示对话框窗口
CView::OnLButtonDown(nFlags,point);
}
( 4 ) 用同样方法为鼠标右键建立消息处理函数
OnRButtonDown,并添加如下代码:
void CNDialogView::OnRButtonDown(UINT nFlags,CPoint
point)
{// TODO,Add your message handler code here and/or call
default
m_pDlg->DestroyWindow();
CView::OnRButtonDown(nFlags,point);
}
返回 47
5.3 非模式对话框的实现
3,增加自己的消息代码 。
( 1) 在 NDialog.h文件中定义 WM_GOOD消息 ID,其中粗体为新添加的代码:
#include "resource.h" // main symbols
#define WM_GOOD WM_USER+5
( 2 ) 在 NDialogView.cpp 文 件 中 添 加 如 下 代 码,
BEGIN_MESSAGE_MAP(CNDialogView,CView)
ON_MESSAGE(WM_GOOD,OnGood)
//{{AFX_MSG_MAP(CNDialogView)
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
返回 48
5.3 非模式对话框的实现
( 3) 在 NDialogView.cpp文件中增加消息处理函数,其中粗体为新添加的代码:
// CNDialogView message handlers
LRESULT CNDialogView::OnGood(WPARAM
wParam,LPARAM lParam)
{ TRACE("CNDialogView::OnGood%x,%1X\n",
wParam,lParam);
(const char*)m_pDlg->m_strEdit1;
m_pDlg->DestroyWindow();
return 0;
}
返回 49
5.3 非模式对话框的实现
( 4) 在 NDialogView.h文件中增加如下函数原型,其中粗体为新添加的代码:
// Generated message map functions
protected:
//{{AFX_MSG(CNDialogView)
afx_msg void OnLButtonDown(UINT nFlags,CPoint point);
afx_msg void OnRButtonDown(UINT nFlags,CPoint point);
//}}AFX_MSG
afx_msg LRESULT OnGood(WPARAM wParam,
LPARAM lParam);
DECLARE_MESSAGE_MAP() };
返回 50
5.3 非模式对话框的实现
4,在 NDialogView,cpp文件中添加头文件包含语句,其中粗体为新添加的代码:
#include "NDialogDoc.h"
#include "NDialogView.h"
#include "NDialog.h"
5,运行并测试应用程序 。
( 1) 编译并运行应用程序 Ndialog。
( 2) 按下鼠标左键,则,非模式对话框,出现 。
( 3) 在对话框外的区域,按下鼠标右键,则,非模式对话框,消失 。
( 4) 再次按下鼠标左键,则,非模式对话框,又出现 。
( 5) 在编辑框中输入内容,单击 【 OK】 按钮,则对话框关闭 。
返回 51
5.3 非模式对话框的实现
5.4 创建对话框的主要步骤要创建一个完整的对话框必须经过两个步骤:一是用资源编辑器创建对话框资源,二是用 Class Wizard来创建对话框类 。 无论是模式对话框还是无模式对话框,这两个步骤都是一样的 。 创建对话框的主要步骤如下:
步骤零,先创建一个应用程序框架 。
步骤一,在已经打开的工程文件中,利用资源编辑器来设计一个含有各种控制件的对话框资源;
步骤二,利用 Class Wizard来创建对话框类,它是由
CDialog类派生的;
步骤三,将对话框资源中的控件与对话框类中的消息处理函数连接起来;
返回 52
5.3 非模式对话框的实现步骤四,利用 Class Wizard添加与对话框控件有关的成员变量,数据交换函数及数据确认函数;
步 骤 五,对 一 些 特 殊 的 控 制 初 始 化 函 数 ( 如
OnIntiaDialog( )) 及消息控制函数进行编辑;
步骤六,把对话框与具体的菜单命令相联系 。
返回 53
本章小结返回 54
习题