530 likes | 636 Views
第五章 对话框及常用控件. 本章导读 在 Windows 应用程序中,对话框( Dialog )是最重要的用户界面元素之一,是应用程序与用户交互的重要手段。当用户进行某项操作之后,弹出一个对话框把反馈信息传递给用户,也可以要求用户输入数据或者进行选择。 控件在 Windows 应用程序中也很常见。一般来说,在对话框中是通过各种控件来和用户进行交互的,我们经常用到的控件有按钮、列表框、编辑框、组合框、滚动条等。实际上,控件是一种特殊类型的窗口,通常为其父窗口所拥有。. 5.1 对话框的组成和分类. 5.1.1 对话框的组成
E N D
第五章 对话框及常用控件 • 本章导读 • 在Windows应用程序中,对话框(Dialog)是最重要的用户界面元素之一,是应用程序与用户交互的重要手段。当用户进行某项操作之后,弹出一个对话框把反馈信息传递给用户,也可以要求用户输入数据或者进行选择。 • 控件在Windows应用程序中也很常见。一般来说,在对话框中是通过各种控件来和用户进行交互的,我们经常用到的控件有按钮、列表框、编辑框、组合框、滚动条等。实际上,控件是一种特殊类型的窗口,通常为其父窗口所拥有。
5.1 对话框的组成和分类 • 5.1.1 对话框的组成 • 在Visual C++中,对话框主要是由对话框资源和对话框类组成: • 1. 对话框资源 • 对话框资源中描述的是对话框的大小、风格等特性,以及对话框中控件的类型和它们的位置。定义对话框资源最简单、最有效的方法就是使用Visual C++中的资源编辑器。 • 2. 对话框类 • 对话框资源所提供的仅仅是一个数据结构,要利用所创建的对话框资源,必须要创建以它作为资源的对话框类,对话框类是从CDialog类中派生出的子类,它提供了编程接口来管理对话框。
5.1 对话框的组成和分类 • 5.1.2 对话框的分类 • 对话框有两种类型:模式对话框和无模式对话框。下面分别对这两种对话框进行说明。 • 1. 模式对话框 • 所谓“模式对话框”是指对话框被弹出后,用户必须在对话框中作出相应的操作;在退出对话框之前,会阻止其他应用程序的运行(包括它所在的应用程序)。 • 一般情况下,模式对话框会有【OK】(确定)和【Cancel】(取消)两个按钮。单击【OK】按钮,系统认定用户在对话框中的选择或输入有效,退出对话框;单击【Cancel】按钮,系统认定用户在对话框中的选择或输入无效,退出对话框,程序恢复原有状态。
5.1 对话框的组成和分类 • 2. 无模式对话框 • 所谓“无模式对话框”是指当对话框被弹出后,将一直保留在屏幕上,但不影响其他应用程序的运行,用户可以继续在对话框所在的应用程序中进行其他操作;当需要使用对话框时,只需像激活一般窗口一样单击对话框所在的区域即可。例如在Microsoft Word中的“查找”和“替换”对话框。 • 两种对话框在用资源编辑器设计和使用Class Wizard 进行编程时的方法基本一致。但在创建和退出窗口时的方式有所不同。
5.1 对话框的组成和分类 • 在创建时,模式对话框是由系统自动分配内存空间,因此在退出对话框时,对话框对象会自动删除。而无模式对话框则是需要用户来指定内存,退出时还需用户自己来删除对话框对象。 • 在退出时,两种对话框所使用的终止函数不一样。模式对话框通过调用CDialog::EndDialog来终止,而无模式对话框则是通过调用CWnd::DestroyWindow 来终止。
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的各个步骤中按下列要求设置选项:
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】按钮,完成应用程序框架的设计。
5.2 创建模式对话框 • 5.2.2 创建对话框资源 • 接下来,我们要做的工作是创建对话框资源,其创建步骤如下: • 步骤一:在打开的工程中,选择【Insert】菜单中的【Resource】菜单项,或直接按Ctrl+R键,系统将弹出【Insert Resource】对话框 • 步骤二:在对话框中选择 【Dialog】选项,然后单击【New】按钮,或直接双击【Dialog】选项,这时对话框资源编辑器将显示在Visual C++平台中,在对话框资源编辑器中显示了一个只有【OK】按钮和【Cancel】按钮的简单的对话框。
5.2 创建模式对话框 • 在新建对话框的同时,在其右边随之出现了一个控件模板,即Controls工具栏,它的作用是向对话框资源中添加控件。工具栏中的每一个图标(除了左上角的指针)都代表一种能够添加到对话框中的控件,我们可以用一种“所见即所得”的方式来向对话框资源添加各种控件。 • 如果仔细观察一下系统的菜单,你就会发现菜单中多了一项【Layout】菜单,而且在状态拦的上面增加了一个新的工具栏——【Dialog】工具栏,其中的按钮在编辑对话框资源和增加控件时是十分有用的工具。下面我们对【Dialog】工具栏进行详细的说明。
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:将选定的多个控件两两之间的水平间隔相同
5.2 创建模式对话框 • 9. Space Down:将选定的多个控件两两之间的垂直间隔相同 • 10. Make Same Width:使选定的多个控件具有相同的宽度,宽度的标准是最后选择的控件 • 11. Make Same Height:使选定的多个控件具有相同的高度,高度的标准是最后选择的控件 • 12.Make Same Size:使选定的多个控件具有相同的高度和宽度,高度和宽度的标准是最后选择的控件 • 13.Toggle Grid:显示或隐藏网格 • Toggle Guides:显示或隐藏标尺
5.2 创建模式对话框 • 步骤三:系统默认产生的对话框的标题是“Dialog”,下 • 面我们来更改一下对话框的标题。 • 选择【View】菜单下的【Properties】菜单项,或对 • 话框窗体上单击鼠标右键,在弹出的快捷菜单中选 • 【properties】菜单项,系统将弹出对话框资源的属性对 • 话框。选择【General】选项卡,在其中的【Caption】 • 框中输入对话框标题的名称为“个人资料”。资源【ID】 • 框中的默认值为IDD-DIALOG1,可以按照自己的需要修 • 改为便个于记忆的标识符。因为此对话框的内容主要用 • 于显示人资料,所以在此示例中,我们将【ID】改为 • “IDD_DIALOG_Mydata”。按“回车”键,完成对话 • 框标题和ID的更改。
5.2 创建模式对话框 • 在Visual C++中,对于不同的控件定义了不同的ID 类型:IDC_是控件的 ID 值(ID of Control) 的前缀;IDD_ 是对话框的ID值( ID of Dialog)的前缀;ID是系统自己缺省的ID值的前缀。 • 步骤四:向对话框中添加控件。向对话框中添加控件的方法有两种: • 1. 在控件工具栏中选择所需要的控件,按下鼠标的左键(不要松开),将鼠标拖到对话框中松开,在对话框中将添加一个指定的控件。 • 2. 在控件工具栏中单击所需要的控件,此时控件将呈凹下状态,将鼠标移至对话框,鼠标此时显示为“十”字形,按下鼠标左键,在对话框上拖动至适当大小,松开鼠标左键,开鼠标左键,在对话框中将添加一个指定的控件。
5.2 创建模式对话框 • 按照上面的方法,我们在对话框资源中添加控件资源,并且按照修改对话框标题的方法对每个控件对ID和Caption进行修改,如表5.1所示
5.2 创建模式对话框 • 步骤五:下面我们来设置一下Tab 键顺序。所谓Tab 键顺序是指当对话框拥有输入焦点时,每次按下Tab 键,对话框中各个控件依次拥有输入焦点的次序。 • 选择【Layout】菜单中的【Tab Order】菜单项,或直接按下 Ctrl+D键,此时对话框中的每一个控件左上角将
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
5.2 创建模式对话框 • 按【Esc】键退出设置Tab键顺序状态。并将以上各个控件的属性中的【Tab Stop】复选框置为选中状态。 • 步骤六:测试生成对话框资源。选择 【Dialog】 工具栏中的【Test】按钮,或者直接按Ctrl+T键,输入焦点应该首先在文本框 IDC_EDIT_NAME上,不断按Tab键,观察输入焦点的变化是否和设置的顺序一致。也可以进行在文本框中输入文本信息、选中单选按钮、选择组合框信息、选中复选框等操作。 • 5.2.3 创建对话框类 • 5.2.3.1创建对话框类并添加成员变量 • 对话框资源已经编辑完成,下面的工作是通过Class Wizard 来创建自己的对话框类。
5.2 创建模式对话框 • 步骤一:在对话框编辑器打开并且显示刚才新创建的对话框资源的情况下,选择【View】菜单中的【Class Wizard】菜单项。Class Wizard会提示将对话框资源和一个类相连接,这个类可以是新创建的类,也可以是已经存在的类。 • 步骤二:接受缺省设置【Creat an new class】,单击【OK】按钮,为对话框资源创建一个新类。系统将会弹出【New Class】对话框。 • 在【Name】编辑框中输入需要生成的对话框类名“CMydataDialog”,在指定对话框类名的同时,Class Wizard将按照给出的对话框类名来自动定义生成的对话框的文件名为“MydataDialog.cpp”。单击【OK】按钮,将继续执行。
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。
5.2 创建模式对话框 • 按照表5.2对其他成员变量进行设置。设置完成后单击【OK】按钮退出。 • 在此要对单选按钮控件进行一下说明,因为它的处理方式与其他控件不同。此例中,我们使用了两个单选按钮,而且它们被定义为一组(通过选中IDC_RADIO_M的
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中输入的字符串的最大长度。 • 这样,对话框中的控件和对话框中的成员变量之间就建立了完全的对应关系,用这种方式生成的变量,系统会自动处理数据交换。
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;
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;
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)
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识别和处理:(括号内为映射变量所属的类)
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用来识别映射变量初始化的结束代码
5.2 创建模式对话框 • 3. 映射变量与对话框控制间的映射宏 • 映射变量与控制间的映射宏代码必须放在在以下两行代码(在函数DoDataExchange()中)之间,才能被Class Wizard识别和处理: • //{{AFX_DATA_MAP(CMydataDialog) //Class Wizard用来//识别映射变量的映射宏的起始代码 • //}}AFX_DATA_MAP //Class Wizard用来//识别映射变量的映射宏的结束代码 • 5.2.4 对话框的实现 • 一般情况下,用户是通过调用菜单项来激活对话框的,在此,我们不妨先通过双击鼠标左键来激活对对话框的调用。具体步骤如下:
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】按钮,在出现的代码编辑窗口中输入以下程序代码。其中粗体部分为新输入的程序代码。
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( )来显 • //示对话框,并且等待用户的响应。
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;
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+="音乐 ";
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"
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】按钮进行编译。
5.2 创建模式对话框 • 步骤五:选择【Build】菜单中【Execute】菜单项,或者单击【Build】工具栏中的【Execute Program】运行程序。 • 步骤六:在窗口中双击鼠标左键,弹出刚刚设计的“个人资料”对话框。 • 可以在编辑框中输入姓名为“王春玲”,选择性别为“女”、最高学历为“硕士”、爱好为“体育”和“音乐”,单击“确定”按钮退出时,将显示消息框如图所示。
5.3 非模式对话框的实现 • 非模式对话框的创建步骤基本上同模式对话框的创建一致,只是实现的原理不一样,在这里只介绍其独特的地方,其它共同部分可参照上一节中所介绍的步骤。 • 模式和非模式对话框共享相同的基类CDialog,并且它们都可以使用对话框编辑器来创建对话框资源。 • 我们可以通过调用成员函数DoModal( )来显示一个有模式的对话框,当函数返回时,对话框将不再存在。而无模式对话框在它本身处于激活状态时,还允许用户使用其他的应用程序。创建无模式对话框要比创建模式对话框复杂一些:首先要调用的默认构造函数构造一个对话框窗口对象;然后通过调用CDialog的成员函数Create来创建对话框窗口,而不是调用成员函数DoModal。并且当对话框仍然留在屏幕上时,控制已经立刻返回了。
5.3 非模式对话框的实现 • 下面,我们就来创建一个简单的非模式对话框,具体步骤如下: • 步骤一:创建应用程序框架。 • 利用App Wizard在“E:\C++\Example\”创建一个应用程序框架“Ndialog”。除了以下两个选项外,其他均使用默认值:选定SingleDocument,并撤消Printing And Print Preview的选定。 • 步骤二:创建对话框资源。 • 1. 选择【Insert】菜单中的【Resource】菜单项,然后选定【Dialog】。 • 2. 设置对话框的标题为“非模式对话框”,ID值使用缺省值“IDD_DIALOG1”。 • 3. 添加两个控件:一个静态文本控件,标题为“输入信息”;一个编辑框控件。二者均使用默认ID值。
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中单
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();
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; • }
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 • }
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(); } • }
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文件中添加如下代码,其中粗体为新添加的代码:
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;}
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】
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
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); • }
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()
5.3 非模式对话框的实现 • (3)在NDialogView.cpp文件中增加消息处理函数,其中粗体为新添加的代码: • // CNDialogView message handlers • LRESULTCNDialogView::OnGood(WPARAM • wParam,LPARAM lParam) • { TRACE("CNDialogView::OnGood%x,%1X\n", • wParam,lParam); • (const char*)m_pDlg->m_strEdit1; • m_pDlg->DestroyWindow(); • return 0; • }
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()};
5.3 非模式对话框的实现 • 4. 在NDialogView. cpp文件中添加头文件包含语句,其中粗体为新添加的代码: • #include "NDialogDoc.h" • #include "NDialogView.h" • #include "NDialog.h" • 5. 运行并测试应用程序。 • (1)编译并运行应用程序Ndialog。 • (2)按下鼠标左键,则“非模式对话框”出现。 • (3)在对话框外的区域,按下鼠标右键,则“非模式对话框”消失。 • (4)再次按下鼠标左键,则“非模式对话框”又出现。 • (5)在编辑框中输入内容,单击【OK】按钮,则对话框关闭。