c++对话框

更新时间:2024-05-19 03:48:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

【上机练习8】:通过建立一个具有禁止和启用功能的菜单的应用程序来完成在单文档界面下对菜单项的操作。通过选择“启用/禁止”命令,完成对相应菜单项的启用和禁止功能的操作。

1. 运行程序,效果如下图

1. 选择“启用”菜单,效果如下图

2. 选择“禁止”菜单,效果如下图

4.要求按图示,在菜单中加一条分隔线。 操作步骤如下:

1.利用AppWizard向导,创建SDI应用程序。文件名为chap8。 2.在ResourceView的资源列表中,单击Menu(菜单)旁边的“+”,再双击IDR_MAINFRAME

选项。在右侧编辑区中将显示建立的菜单资源。

3.双击空白的虚框,打开菜单属性对话框,输入主菜单标题“禁止/启用(&J)”。

4.在已建立的菜单项下出现了新的空白虚框,选中空白虚框,输入“菜单项一”,ID号为ID_NO1。

5.按上面的方法输入“菜单项二”,ID号为ID_NO2。 6.增加一条分隔线。再建立新的菜单项“禁止”, ID号为ID_NO、“启用” ID号为ID_USE. 7.添加成员变量。在ClassView选项卡,并展开其选项,双击chap8选项。在CMainFrame选项上右击,在快捷菜单中选Add Member Variable(添加变量) 命令,打开“添加变量”对话框。在对话框中输入变量名—status、变量类——BOOL,选择变量属性——private。此时会看到在Cchap7Doc下面自动添加了一个变量status。变量status用来作为ID_NO1和ID_NO2的状态识别变量。 8.为“启用”菜单项添加成员函数OnUse()。在MFC Class Wizard对话框中,选Message Maps选项卡,进行如下设置:

选择Class name: CMainFrame Object IDs: ID_USE Messages:COMMAND 添加成员函数OnUse(), 代码如下: //TODO

status=TRUE;

9.为“禁止”菜单项添加成员函数OnNo()。设置同上。

Class name: CMainFrame Object IDs: ID_NO Messages:COMMAND 代码如下: //TODO

status=FALSE;

10.为“菜单项一”菜单项添加成员函数OnUpdateNo1()。设置同上。

Class name: CMainFrame Object IDs: ID_NO1 Messages:UPDATE_COMMAND_UI 代码如下: //TODO

switch(status)

{ case FALSE: //状态标识为“禁止”

pCmdUI->Enable(FALSE);//对应菜单为“禁止”状态

break;

case TRUE: //状态标识为启用

pCmdUI->Enable(TRUE);// 对应菜单为“启用”状态 break; }

11.同时为“菜单项二”菜单项添加成员函数。

Class name: CMainFrame Object IDs: ID_NO2 Messages:UPDATE_COMMAND_UI 代码如下: //TODO

switch(status)

{ case FALSE: //状态标识为“禁止”

pCmdUI->Enable(FALSE);//对应菜单为“禁止”状态

break;

case TRUE: //状态标识为启用

pCmdUI->Enable(TRUE);// 对应菜单为“启用”状态 break;

}

※ 本题并没有对“菜单项一”和“菜单项二”的功能进行具体设置。只是对菜单项状态进行了禁止和启用的设置。

第7章 对话框

对话框在Windows系统环境中应用很普遍,它通常作为应用程序与用户交互的场所,是用户向应用程序传递信息的工具。对话框是一个特殊类型的窗口,任何对窗口进行的操作,均可在对话框中进行操作。与Visual C++的其他窗口相比,对话框的最大优点还在于它更易于放置控件来和用户进行交互。 7.1对话框效果要求

对话框主要分为模式对话框和无模式对话框。模式对话框是指这种对话框出现时,它的父窗口将暂时失效,只有处理完对话框要求的工作后,才会将控制权交回给父窗口。无模式对话框不会使父窗口失效,因此,无模式对话框出现时,可以继续执行父窗口的操作。无模式对话框使用的很少,大部分使用的是模式对话框。

本例mydlg应用程序讲述对话框的开发过程。完成对模式对话框和无模式对话框的调用,同时完成对话框与应用程序的数据交换。

在mydlg应用程序中,要求建立如图7.1所示的应用程序界面,其具体设计要求如下: (1)在菜单栏中,增加“对话框”菜单项,及“模式对话框”和“无模式对话框”子菜单项。

(2)单击“模式对话框”菜单项,调出一个“人员情况”模式对话框,如图7.2所示。可以输入工作人员的姓名、年龄、性别、学历、联系电话、个人主要经历等信息。

(3)单击“无模式对话框”子菜单项,调出一个无模式对话框,如图7.3所示,可以在无模式对话框和父窗口间切换。当单击OK按钮时,无模式对话框显示“您正在使用无模式对话框!”,当用鼠标单击其父窗口时,无模式对话框显示“您已经离开无模式对话框!”。

7.2 程序实现过程

7.2.1 创建工程

按以下步骤建立Menu.exe程序的工程和框架文件:

(1)创建工程,选择AMFC AppWizard(exe)选项,输入文件名mydlg和保存位置。“确定”。

(2)进入MFC应用程序向导步骤1,选择“单个文档”。 (3)以下设置全部选择为默认。 (4)单击“完成”。 (5)单击“确定”。

AppWizard将完成应用程序的自动生成。 7.2.2 可视化设计 1.主窗口菜单栏的设计

在应用程序的菜单中,添加一个新的菜单项——“对话框”。 在ResourceView的资源列表中,单击Menu旁边的“+”,再双击IDR_MAINFRAME选项,如图7.5所示。打开菜单资源编辑器,显示如图7.6所示的默认菜单资源。双击该菜单的空菜单项,在弹出的对话框中按图7.7输入,增加一个“对话框”菜单项。

在“对话框”下拉菜单底部有一个空选项,双击它,定义两个新的菜单选项,如图7.8所示新添“模式对话框”和“无模式对话框”两个新的菜单选项。模式对话框的ID号为:ID_MODAL, “无模式对话框”的ID号为:ID_MODELESS。

设计了菜单栏后,还需要对新添加的菜单增加快捷键。在ResourceView的资源列表中,

单击Accelerator旁边的“+”,再双击IDR_MAINFRAME选项,打开快捷键资源编辑器,如图7.9所示。在快捷键资源编辑器的最下面一行右击,在弹出的菜单中选择New Accelerator(新建加速栏)选项,显示快捷键属性对话框,按如图7.10所示输入“模式对话框”和“无模式对话框” 菜单项所对应的快捷键的属性。“模式对话框”为Ctrl+M,“无模式对话框”为Ctrl+L。

创建对话框的方法有两种:

1)利用应用程序向导直接建立基本对话框。

2)在单文档或多文档的方式下,在资源中选项卡中添加对话框。 2.创建模式对话框资源

可以通过下面的步骤建立对话框,设计完成后如图7.11所示。

(1)在ResourceView的资源列表中,右击Dialog选项,弹出如图7.12所示的快捷菜单,在快捷菜单中选择InsertDialog选项,添加新的对话框如图7.13所示。

在对话框资源编辑器中,右击对话框,在弹出的快捷菜单中选择“属性”,设置对话框的属性,如图7.14所示,将对话框的ID项内容更改为IDD_MODAL,在“标题”项中填入“个人情况”,还可以设置字体等。

(2)在对话框中添加控件

控件是在系统内部定义的能够完成特定功能的控制程序单元。在应用程序中使用控件不仅简化了编程,还能完成常用的各种功能。为了更好地发挥控件的作用,用户应理解和掌握控件的属性、消息以及创建和使用的方法。关于控件工具栏,我们在第四章已经介绍过。

可以使用控件工具栏为对话框中添加控件。 ①使用静态文本控件

通常用来显示一段字符串。如“姓名”、“年龄”、“性别”、“联系电话”、“学历”、“主要经历”等,可以通过静态文本控件的属性中的标题来设置。 ②使用编辑控件

编辑控件通常让用户输入文字或数据、或进行修改等工作。使用编辑控件在对话框中添加“姓名”、“年龄”、“联系电话”、“主要经历”等的输入编辑框。利用编辑框的属性,在ID栏中输入一个有意义的新的ID号。其中“姓名”为IDC_NAME、“年龄”为IDC_AGE、“联系电话”为IDC_TEL、 “主要经历”为IDC_LIVE。如图7.17所示就是编辑控件的属性对话框。还可以在其中设置文本对齐方式、文本多行显示及口令输入方式等。对于“主要经历”应该设置文本多行显示。 ③使用分组框和单选按钮

分组框和单选按钮在前面我们已经使用过,单选按钮通常被放置在分组框内。任何将这些毫无关系的单选按钮组成一组呢?将一组第一个放置单选按钮的Group(组)属性设置为复选,就可以实现在一组单选按钮中,每次只能有一个按钮被选中。

需要添加“性别”分组,添加一个分组框,其属性如图7.18所示。在分组框中添加两个单选按钮,分别对应“男”和“女”,按照图7.19设置属性,其中“男”单选按钮的Group(组)属性设置为复选。 ④使用组合框控件

组合框包含编辑控件和列表框,是控件中比较复杂的一个。使用组合框完成对“学历”情况的输入。在组合框控件“属性”中,“学历”的号ID为IDC_DEGREE。在Data属性中添加学历列表(使用Ctrl+Enter结束当前项输入并换行),将Styles标签中是Sort(分类)选项删除,如图7.20所示。

※在使用组合框控件时,一定要在编辑时将组合框控件拉出来,(单击▼按钮可以向下拉动)。否则在运行时不能做下拉演示。

(3)控件位置调整

在VC++工具栏上右击,弹出如图7.21所示的工具栏快捷菜单,选择Dislog选项,在VC++工具栏中增加一个“编排”工具栏如图7.22所示,利用此工具栏就可以对对话框进行调整,调整后的对话框如图7.23所示。 (4)设定Tab键切换顺序

当对话框弹出的时候,每一种操作都有键盘焦点,只有具有焦点的控件才能从键盘获得输入,可以通过键盘上的Tab键来切换输入焦点。

控件总是按照一定的顺序被选择,这个顺序是可以被改变的。在VC++的菜单栏上“布局”菜单项的下拉菜单中选择“Tab 顺序”选项,此时在对话框中每个控件的左上角都会出现一个数字,这个数字就是次序号,如图7.24所示。按照需要的顺序单击控件,按Enter键结束。

(5)测试对话框设计完后,需要先测试一下,看它是否满足要求。在VC++的菜单栏上“布局”菜单项的下拉菜单中选择Test”测试”选项,VC++会将设计好的对话框显示出来,以供测试,按Esc键结束。 (6)创建对话框类

对已经设计完成的对话框资源,为了在应用程序中调用该对话框,还需要为其创建相应的对话框类。(对话框的基类为CDialog,用户为程序增加了一个对话框,就要创建一个派生新子类,对应这个对话框)。双击对话框,显示如图7.25所示的Adding a Class对话框,可以为对话框添加新类。单击OK按钮,显示如图7.26所示的New Class对话框,按图7.26输入所需内容,为对话框创建Cdialog的派生类Cmymodal类。

对话框的派生新子类 3.创建无模式对话框资源

创建无模式对话框资源和创建模式对话框资源的步骤一样,利用上述的方法创建如图7.27所示的无模式对话框,ID号为IDD_MODELESS并创建无模式对话框类Cmymodeless。 至此,已完成主窗口界面的设计,可以编译和执行程序。下面应该为应用程序添加相应对话框的基类 对话框的ID号

的程序代码。

7.2.3 代码编写

1.模式对话框的代码编写 (1)增加数据成员变量

从“查看”菜单选“建立类向导”,出现MFC Class Wizard对话框,选择Member Variables标签,如图7.28所示,确认Project列表框中的内容为mydlg,Class name列表框中的内容为CMYMODAL,在Control IDs列表框中选中“年龄”控件的ID号,并单击Add Variables按钮,弹出如图7.29所示的Add Member Variables对话框,按照图7.29所示输入相应的输入项,为“年龄”控件增加m_age数据成员变量。按照以上的方法为“人员情况”对话框中的各控件增加相应的数据成员变量。对于单选按钮控件,在Control IDs列表框中只给出一个ID号,即IDC_SEX,对话框类使用一个成员变量控制一组单选按钮控件,该组单选按钮控件对应变量的值为0、1、2、??。

MFC Class Wizard自动在(FileView选项卡,展开Header File,在)mymodal.h文件中自动增加成员变量的声明,如下所示: Public:

CMYMODAL(CWnd* pParent=NULL); // enum{IDD=IDD_MODAL}; int m_age; //年龄

Cstring m_degree; // 学历 Cstring m_live; //主要经历 Cstring m_name; //姓名 int m_sex; //性别 Cstring m_tel; //电话

同时自动在(Source File 选项卡中)mymodal.cpp文件中产生一些初始化对话框中控件的代码,其中包含控件的初始化代码,并定义了空间与数据成员变量的对应关系。Class Wizard自动生成的代码如下:

Cmymodal::Cmymodal(CWnd* pParent /*=NULL*/) : CDialog(Cmymodal::IDD, pParent) { {{AFX_DATA_INIT(Cmymodal) m_age = 30; m_degree = _T(\大本\ m_live = _T(\ m_name = _T(\张旭\ m_sex = -1; m_tel = _T(\ //}}AFX_DATA_INIT }

void Cmymodal::DoDataExchange(CDataExchange* pDX)

{ //DoDataExchange()函数定义了控件与数据成员变量的对应关系,用于实现对对话框中的内容进行数据交换和数据校验的功能。这部分是系统自动建立的。

CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(Cmymodal) DDX_Text(pDX, IDC_AGE, m_age); DDX_CBString(pDX, IDC_DEGREE, m_degree);

DDX_Text(pDX, IDC_LIVE, m_live); DDX_Text(pDX, IDC_NAME, m_name); DDX_Radio(pDX, IDC_SEX, m_sex); DDX_Text(pDX, IDC_TEL, m_tel); //}}AFX_DATA_MAP }

????(见151-152页)

在(ClassView选项卡,找到)构造函数CMYMODAL∷CMYMODAL()中可以完成对成员变量的初始化工作,在此应用程序中,对各成员变量的赋值如下:(当然,不做初始化也可以)

m_age=30;

m_degree=_T(“大本”); m_live=_T(“ ”);

m_name=_T(“张旭”); m_sex=1;

m_tel=_T(“13912345678 ”);

DoDataExchange()函数定义了控件与数据成员变量的对应关系,用于实现对对话框中的内容进行数据交换和数据校验的功能。 (2)增加OnInitDialog()函数

从“查看”菜单选“建立类向导”,出现MFC Class Wizard对话框,选择Member Maps标签,确认Project列表框中的内容为mydlg,Class name列表框中的内容为CMYMODAL。然后在Object IDs列表框中选CMYMODAL选项,在Messages列表框中选择WM_INITDIALOG消息,如图7.30所示,单击Add Function按钮,为WM_INITDIALOG消息增加消息响应函数OnInitDialog(),单击Edit Code按钮,在函数中添加如下代码:

CComboBox *cmb=(CComboBox *)GetDlgItem(IDC_DEGREE); cmb->InsertString(-1,”高中”); cmb->InsertString(-1,”中专”);

向“学历”组合框中再添加两个数据项——”高中”和”中专”。 GetDlgItem()函数用于得到一个指向所需控件的指针,其函数原型如下:

CWnd* GetDlgItem(int nID) const;

通过CcomboBox类成员函数InserString(),向组合框中添加新的数据项,其函数原型如下:

int InsertString(int nIndex, LPCTSTR lpszString); 其中int nIndex指明插入组合框中数据列表的位置,当nIndex为-1时,在数据列表的最后插入,LPCTSTR lpszString为要插入的字符串。 2.模式对话框的调用

(1)增加菜单的消息响应函数

从“查看”菜单选“建立类向导”,出现MFC Class Wizard对话框,选择Member Maps标签,确认Project列表框中的内容为mydlg,Class name列表框中的内容为CMydlgView。然后在Object IDs列表框中选ID_MODAL选项,在Messages列表框中选择COMMAND消息,单击Add Function按钮,为COMMAND消息增加消息响应函数OnModal(),如图7.31所示,单击Edit Code按钮,在函数中添加如下代码:

Cmymodal mymodal; //为对话框创建一个对象,相当于添加对话框变量。 if(mymodal.DoModal()==IDOK)

{

mymodal.MessageBox(“输入信息正确吗?”, “个人情况”,MB_YESNO); }

对于对话框的调用分成两步,首先要构造一个对话框对象——CMYMODAL mymodal,然后调用对话框对象的成员函数DoModal()来装载对话框资源,显示对话框,并管理与对话框对象的交互,直到单击对话框中的OK或Cancel按钮结束。调用MessageBox()函数弹出消息框,用于确认输入信息的正确性。

(2)添加mymodal.h的说明(这里正确添加头文件很重要,这个添加如果不做,前一步操作后编译就会出错)

在mydlgView.cpp中用到了COMYMODAL类,因此需要将COMYMODAL类的头文件的说明加入到(FileView选项卡Source File下面的)mydlgView.cpp中: #include “mymodal.h”

编译并执行程序,单击“对话框”菜单中的“模式对话框”子菜单时,弹出“人员情况” 对话框,在其中输入所需信息后,单击OK按钮,弹出如如图7.32所示的消息框,确认输入正确后,单击“是”按钮。6/3

建立模式对话框的步骤:

1. 建立Menu.exe程序的工程和框架文件。 2. 添加一个新的菜单项——“对话框”。 3. 添加的菜单快捷键。 4. 添加新的对话框。 5. 在对话框中添加控件。 6. 设定Tab键切换顺序。

7. 创建对话框类。如果是在单文档中调用对话框则需要创建对话框类。如果是单独使

用对话框则不需要创建对话框类。 8. 为控件增加数据成员变量。 9. 完成对成员变量的初始化工作。

10. 增加OnInitDialog()函数。完成对话框的初始化。 11.添加对话框变量。模式对话框的调用,增加菜单的消息响应函数,激活模式对话框。 12. 添加mymodal.h的说明 1. 无模式对话框的代码编写和调用

调用无模式对话框,需要在子对话框类中编写自己的公有构造函数。在调用时,通过调用该构造函数构造对话框对象。然后调用对话框对象的Create()成员函数加载对话框资源,如果对话框资源具有WS_VISIBLE属性,那么对话框立即显示,否则需要调用ShowWindow()函数显示该无模式对话框。对于无模式对话框的关闭,需要调用DestroyWindow()函数删除该对话框。

(1)无模式对话框函数代码的编写

在mydig的Workspace窗口的Class View的资源列表中,右击Cmymodeless,弹出如图7.33所示的快捷菜单,在菜单中选择Add Member Variable选项,出现Add Member Variable对话框,按照图7.34所示添加数据成员变量m_parent,用于存放产生无模式对话框的父窗口。在构造函数中对进行初始化,其代码如下: m_parent=pParent;

错误“error C2582: ' CSomeClass ' : 'operator =' function is unavailable”是指在程序中出现了CSomeClass类对象的赋值操作,但类中却没有“=operator”操作的声明和实现,如“sc = class_list.GetPrev(pos);”。

再在图7.33所示的快捷菜单中选择Add Member Function选项,弹出如图7.33所示的Add Member Function对话框,增加Creat()函数。为Creat()函数添加代码如下: return Cdialog::Create(Cmymodeless::IDD, m_parent);

其中Cmymodeless::IDD为在mymodeless.h中定义的IDD_MODELESS,m_parent为调用该无模式对话框的父窗口,在构造函数中已对其进行了初始化。

为无模式对话框的按钮添加代码。从“查看”菜单选“建立类向导”,出现MFC Class Wizard对话框,选择Member Maps标签,确认Project列表框中的内容为mydlg,Class name列表框中的内容为Cmymodeless。然后在Object IDs列表框中选IDOK选项,在Messages列表框中选择BN_CLCKED消息,如图7.36所示.单击Add Function按钮,为WM_INITDIALOG消息增加消息响应函数OnOk(),单击Edit Code按钮,在函数中添加如下代码:

{CEdit *m_edit=( CEdit *)GetDlgItem(IDC_EDIT1); CString str=”您正在是使用无模式对话框!”; m_edit->SetWindowText(str);}

利用同样的方法为Cancel按钮添加BN_CLICKED消息的消息响应函数OnCancel(),函数代码如下:

DestroyWindow();

在模式对话框中,通过单击OK或Cancel按钮来关闭对话框,Cdialog类提供两个默认的处理函数OnOk()和OnCancel(),在其中调用Cdialog类的EndDialog函数关闭对话框。而当关闭或删除无模式对话框时,需要调用DestroyWindow()函数,所以在OnOk()和OnCancel()函数中将调用Cdialog类默认的函数OnOk()和OnCancel()的代码行注释掉。当单击OK按钮时,编辑框显示”您正在是使用无模式对话框!”,当单击Cancel按钮时,调用DestroyWindow()函数删除该无模式对话框。

在无模式对话框中收到的最后一个消息是WM_NCDESTROY,无模式对话框将调用CWnd类的默认处理函数PostNcDestroy来处理,在这个函数中将释放分配给Cmymodeless的内存。通过以上添加函数的方法,利用MFC Class Wizard对话框,为Cmymodeless类的PostNcDestroy消息添加PostNcDestroy()函数,其函数代码如下:

delete this;

(2)对无模式对话框的调用

按照无模式对话框中增加变量的方法,为CMydlgView类增加如下变量: public:

Cmymodeless *mymodeless; BOOL m_modeless;

其中Cmymodeless *mymodeless;用于存放新创建的无模式对话框的指针,BOOL m_modeless; 用于存放无模式对话框是否正确创建的返回值。

按照无模式对话框添加菜单响应函数的方法,利用MFC Class Wizard对话框,为CMydlgView类的ID_MODELESS的COMMAND消息添加OnModeless()函数,其函数代码如下:

mymodeless=new Cmymodeless(this); m_modeless= mymodeless->Create();

CWnd *m_edit1= mymodeless->GetDlgItem(IDC_EDIT1); m_edit1->SetWindowText(”您正在是使用无模式对话框!”);

通过调用new创建无模式对话框,为其分配内存,并利用mymodeless对象的成员函数Create()创建对话框资源。然后通过GetDlgItem()和SetWindowText()函数初始化无模式

对话框。

当焦点转移到父窗口时,无模式对话框的编辑框中显示“您已经离开无模式对话框!”,为实现这个功能,需在CMydlgView类中添加“WM_SETFOCUS”的消息响应函数OnSetFocus(),其函数代码如下:

if(m_modeless)

{ CWnd *m_edit1= m_modeless->GetDlgItem(IDC_EDIT1); m_edit1->SetWindowText(”您已经离开无模式对话框!”); }

为了成功调用无模式对话框,还需要在中添加类的头文件mymodeless.h #include “mymodeless.h”

编译并执行程序,单击“对话框”菜单项的“无模式对话框”子菜单,弹出“无模式对话框” 对话框窗口,在窗口中单击OK按钮时,编辑框中显示”您正在是使用无模式对话框!”,而将焦点切换到父窗口时,编辑框中显示“您已经离开无模式对话框!”。至此,已完成了mydlg 应用程序的设计。

7.3 理论总结

7.3.1 对话框的设计

模式对话框和无模式对话框的设计思想基本一致,通过对话框资源管理器设计对话框资源,设计对话框资源的方法如下:

(1)创建对话框资源,并添加各种所需的控件。

(2)创建对话框的派生类,并将其与已创建的对话框资源相连。

(3)在创建的派生类中添加所需的数据成员变量、数据交换和数据校验函数。 (4)为对话框及其中的函数添加所需的响应函数。 7.3.2 模式对话框的调用 1.显示对话框

要显示对话框,首先要调用两个CDialog公有构造函数中的任何一个来构造对话框对象,然后调用对话框对象的成员函数Domodal()装载对话框资源、显示对话框并管理与对话框的交互作用,直到单击OK或Cancel按钮。 2.初始化对话框

创建对话框后,可以调用对话框对象的成员函数OnInitDialog()来初始化对话框,模式对话框在调用DoModal()函数时,调用OnInitDialog()函数。 3.处理对话框消息

对话框也是Winsows窗口,对话框的建立、用呼对对话框中各种控件的操作和对话框的结束都将产生消息,对话框必须适当的处理这些消息。 4.关闭对话框

当在对话框中单击OK或Cancel按钮时,可以关闭对话框,在OK或Cancel按钮的默认处理函数中,将调用CDialog类的成员函数EndDialog()来关闭窗口,程序员可以不重设成员函数OnOK()和OnCancel()。 5.加入头文件

在实现对话框的操作时,应将新产生的对话框派生类所对应的.h头文件加入到调用对话框的源文件中。

7.3.3 无模式对话框的调用

无模式对话框和模式对话框的使用方法差不多,只是在对话框的定义、创建以及消息处理上略有差别。 1.显示对话框

无模式对话框的显示和模式对话框的显示有所不同,无模式对话框利用了Create()函数来显示,而不是使用Domodal()来装载对话框资源。

对于无模式对话框首先要定义一个对话框的指针,再通过调用new为其分配内存,最后调用Create()函数来装载对话框资源并显示对话框。

Cmymodeless *mymodeless;

m_modeless=new Cmymodeless(this); m_modeless= m_modeless->Create(); 2.初始化对话框

创建对话框后,可以调用对话框对象的成员函数OnInitDialog()来初始化对话框,无模式对话框在调用Create()函数时,调用OnInitDialog()函数。 3.处理对话框消息

无模式对话框对于消息的处理与模式对话框一样。 4.关闭对话框

模式对话框通过调用CDialog类的成员函数EndDialog()来关闭窗口,而无模式对话框通过调用Create()函数装载,必须调用DetroyWindow()函数来删除相应的窗口。所以在无模式对话框中必须重设OnOK()和OnCancel()函数,当单击OK或Cancel按钮退出对话框时,需在OnOK()和OnCancel()函数中调用DetroyWindow()函数。

对于DetroyWindow()函数的调用只是删除相应的对话框,而并不释放分配给对话框的内存。程序员可以利用窗口的最后一个消息WN_NCDESTROY来释内存,在WN_NCDESTROY的消息响应函数PostNcDestroy中调用delete释放为 放中当单击OK或Cancel按钮时,可以关闭对话框,在OK或Cancel按钮的默认处理函数中,将无模式对话框分配的内存。如应用程序中代码:

delete this; 5.加入头文件

在实现对话框的操作时,应将新产生的对话框派生类所对应的.h头文件加入到调用对话框的源文件中。

7.3.4 对话框数据交换和校验

对话框的一个主要任务是采集用户的输入信息,将输入信息传递给应用程序。用户输入的信息是否正确,也是十分重要的问题。例如:输入了“5月45日”,就是一个明显的错误。如何在对话框中简单的查出这种错误?可以利用MFC所提供的DDX和DDV来解决数据交换与检查的问题。所谓DDX是指把对话框类中的成员变量与对话框中的控件产生关联,当对话框结束时,控件的内容会自动传递到这些成员变量上。所谓DDV是指允许程序员设定对话框的内容类型及数据(数值)范围。

MFC的DDX和DDV的工作流程是:首先在对话框类中定义一些与相对应的成员变量,然后再重载成员函数CWnd∷DoDataExchange(),在这个函数中插入DDX和DDV函数。CWnd∷UpdateData()

DoDataExchange()函数会被CWnd∷UpdateData()函数调用,在CDialog∷OnInitDialog()函数中默认调用CWnd∷UpdateData()函数来初始化对话框控件,当用户单击Ok按钮时,也在CDialog∷OnOk()函数中默认调用CWnd∷UpdateData()函数将控件的值传递给成员变量。UpdateData()函数的原型为:

BOOL Up dateData(BOOL bSaveAndValidate = TRUE); 如果bSaveAndValidate值为TRUE,则获取并验证对话框数据。图7.37为DoDataExchange()信息交换流程。

DDX()函数一般有三个参数:第一个参数是指向CdataExchange对象的指针,第二个参

数是控件资源ID,第三个参数是成员变量。

163页是DoDataExchange()函数重载的例子。

7.3.5 信息框

信息框可以用来与用户进行简单的沟通,在信息框中可以输入标题、信息框中间的文字信息、图标符号以及信息框带有的按钮等。图7.38为一个标准的信息框。要产生信息框,需要用CWnd类的成员函数MessageBox(),其函数原型如下:

int MessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption=NULL,UINT nType=MB_OK);

其中LPCTSTR lpszText为信息框中要显示的文本, LPCTSTR lpszCaption为信息框的标题,UINT nType为信息框的样式,包含其所含有的按钮及其信息文本旁出现的图案,它可以由表7.1所表示的常数组成。MessageBox()函数的返回值为信息框上的哪一个按钮被按下。

7.3.6 通用对话框类

通用对话框是Windows预定的对话框,可以通过对通用对话框的调用,执行各种标准的操作。每个通用对话框都是从CCommonDialog类派生的,而CCommonDialog类又是从CDialog类派生的。表7.2说明各通用对话框的名称和作用。

CDialog类是所有对话框类的基类。它定义了一个构造函数和一个Create()成员函数来创建对话框。CDialog类中有许多成员函数,其中最重要的有4个: 1) CDialog::DoModal();用于激活模式对话框。 2) CDialog::OnlnitDialog();用于响应WM_INITDIALOD消息。 3) CDialog::OnOK();单击确定按钮时,调用该函数。 4) CDialog::OnCancel();单击取消按钮时,将自动终止模式对话框。 1. CFontDialog类

CFontDialog类封装了Windows标准的“字体”对话框,使用户可以从系统安装的字体列表中选择要用的字体,在编程中按照如下步骤使用该对话框: (1)构造CFontDialog类对象。

(2)通过对象的数据成员m_cf初始化对话框中各控件的值或状态。 (3)使用成员函数DoModal()调用对话框。

(4)应用程序通过CFontDialog类的成员函数获得各种信息。 其常用的成员函数如表7.3. 2. CFileDialog类

CFileDialog类封装了Windows标准的“打开”和“另存为”对话框,在编程中按照如下步骤使用该对话框:

(1)构造CFileDialog类对象。

(2)通过对象的数据成员m_ofn初始化对话框中各控件的值或状态。 (3)使用成员函数DoModal()调用对话框。

(4)应用程序通过CFileDialog类的成员函数获得各种信息。 其常用的成员函数如表7.4 3. CColorDialog类

CColorDialog类封装了Windows标准的“颜色”对话框,在编程中按照如下步骤使用该对话框:

(1)构造CColorDialog类对象。

(2)通过对象的数据成员m_cc初始化对话框中各控件的值或状态。 (3)使用成员函数DoModal()调用对话框。

(4)应用程序通过CColorDialog类的成员函数获得各种信息。

其常用的成员函数如表7.5。 4. CPrintDialog类

CPrintDialog类封装了Windows标准的“打印”和“打印设置”对话框,处理打印程序时,在编程中按照如下步骤使用该对话框:

(1)构造CPrintDialog类对象。

(2)通过对象的数据成员m_fr初始化对话框中各控件的值或状态。 (3)使用成员函数DoModal()调用对话框。

(4)应用程序通过CPrintDialog类的成员函数获得各种信息。 其常用的成员函数如表7.6。 5. CFindReplaceDialog类

CFindReplaceDialog类封装了Windows标准的“查找”和“替换”对话框,它允许输入待查找和替换的字符串,“查找”和“替换”对话框是无模式对话框,在编辑中按照如下步骤使用该对话框:

(1)构造CfindReplaceDialog类对象指针,用new操作符为CFindReplaceDialog 类对象分配内存。如CfindReplaceDialog *findreplacedlg=new CfindReplaceDialog ();

(2)通过修改对象的数据成员m_fr初始化对话框中各控件的值或状态。 (3)调用成员函数Create()装载无模式对话框。

(4)应用程序通过CprintDialog类的成员函数获得各种信息。 其常用的成员函数如表7.7。

【上机练习9】利用【上机练习7】的单文档,在其中增加一个对话框,构成一个学生个人

信息登记的操作界面,包含学生姓名、学号、性别、学院及其他信息。 操作步骤如下: 一、建立工程

1. 打开chap7工程。单文档窗口。

2. 选择项目工作区窗口中的ResourceView的资源列表,展开Dialog选项,双击

IDD_ABOUTBOX选项,在右侧会打开一个对话框。该对话框为系统自带的对话框,提供用户使用的应用程序版本和版权声明等消息,用户可对其文字内容进行更改。该对话框与“帮助”菜单项下的“关于”子菜单相对应。

3. 在ResourceView的资源列表中,在Dialog选项上右击,在弹出的快捷菜单中选

InsertDialog命令,Dialog选项下会自动添加IDD_DIALOG1的选项,在右侧打开对

话框供用户编辑。

4. 在对话框上添加静态文本框,一共7个,用属性对话框中的标题,分别显示“学生

个人信息登记”、“姓名”、“学号”、“性别”、“学院”、“其他”和“学生信息”。 5. 在对话框上添加编辑框,一共3个,分别用来显示“姓名”、“学号”和“学生信息”

的内容。

6. 设置编辑框的属性。右击编辑框,打开“属性”对话框。3个编辑框的ID号分别为:

ID_EDIT1,ID_EDIT2,ID_EDIT3。“学生信息”(ID号为ID_EDIT3)的编辑框,在“属性”对话框中选Styles选项卡,选中以下两个复选框:Multiline(允许多行输入),Vertical scroll(当文本行数超过当前可显示范围,增加垂直滑动条) 7. 在对话框上添加单选按钮,一共2个,用来选择“性别”。用属性对话框中的标题

分别设置“男”“女”,不改ID号。

8. 在对话框上添加组合框,用来显示“学院”的信息。在“属性”对话框中选Data

选项卡,输入以下内容:“电气信息学院、自动化学院、机械学院、外语学院、能源环境学院”。每录入一个学院名字,用Ctrl+Enter进行换行。

9. 在对话框上添加复选框,一共2个,用属性对话框中的标题分别设置“班干部”和

“学生会干部”,不改ID号。

10. 至此,对话框上的控件已经添加完毕,调整控件布局。 二、在菜单栏中增加“显示对话框”菜单项

1.选择项目工作区窗口中的ResourceView的资源列表,展开Menu选项,双击IDR_MAINFRAME选项。

2.在右侧编辑区中,添加新菜单项“显示对话框”。

3.再建立一个名为“显示”的子菜单项其ID定义为ID_SHOWDIALOG. 4.为对话框建立新类。回到项目工作区窗口,展开Dialog文件夹,双击IDD_DIALOG1选项,打开前面已经建好的对话框,再打开MFC Class Wizard对话框和Adding a Class对话框,选中Create a new class单选按钮,单击OK按钮,打开new class对话框,在Name文本框中输入“CMYdialog”,然后单击OK按钮。

5.为菜单项“显示对话框”建立函数OnShowdialog。在MFC Class Wizard对话框中: Class name CChap9View

Object IDs ID_SHOWDIALOG//显示菜单的ID号

双击Messages列表框中的COMMAND选项,此时在Member functions列表框中将出现OnShowdialog ON_ID_SHOWDIALOG:COMMAND成员函数。单选“确定”按钮,回到主窗口。

6.为对话框添加变量。右击CChap9View选项,选择Add Member Variable命令,打开Add Member Variable对话框。在Variable Type 文本框中输入“Cmydialog”,在Variable Name文本框中输入”mydialog”,选中“Protected”,然后单击OK按钮。这样就建立了一个名为”mydialog”的“Cmydialog”类保护型对象。

7.添加“显示对话框”函数的语句。展开Cchap7View选项,双击OnShowdialog()选项,(也可以在“建立类向导”中进入函数)在函数体内添加语句:

mydialog.DoModal();//显示对话框

运行该程序,选择“显示对话框/显示”命令,就可以看到运行的对话框了。 三、对话框的编程

1.按Ctrl+W键,打开MFC ClassWizard对话框,选择Member Varables选项卡,在Class name下拉列表中选择Cmydialog选项,在列表框中出现了对话框中控件的ID。

2. 为对话框的控件添加变量,选择某ID号单击Add variable按钮,打开Add Member

variable对话框,按以下表项增加变量。 ID IDC_CHECK1(复选框) IDC_CHECK2(复选框) IDC_COMBO1(组合框) IDC_EDIT1(编辑框) IDC_EDIT2(编辑框) IDC_EDIT3(编辑框) Member variable name Category m_ban m_xuesheng m_xueyuan m_name m_num m_info Value Value Value Value Value Value Variable type BOOL BOOL CString CString CString CString 3.在MFC ClassWizard对话框,选择Member Maps选项卡,为控件增加消息,按以下表项增加消息。 Class name Cmydialog Cmydialog Cmydialog Cmydialog Cmydialog Cmydialog Object IDs IDOK(确定按钮) IDCANCEL(清除按钮) IDC_ CHECK1(复选框1) IDC_ CHECK2(复选框2) IDC_RADIO1(单选框1) IDC_RADIO2(单选框2) Messages BN_CLICKED BN_CLICKED BN_CLICKED BN_CLICKED BN_CLICKED BN_CLICKED 在Cmydialog项目中,可以看到已经自动添加了成员函数和成员变量。

4.在Cmydialog选项上右击,选择Add Member variable命令按以下表项增加成员变量。sex是用来存放选择的单选框的性别值,other是用来存放选择的复选框的“班干部”与“学生干部” 值。

Variable type CString CString Variable name sex other Access public public 5.在Class View选项卡下,展开Cmydialog项,双击Cmydialog[CWnd*pParent=NULL]函数,并将函数体内容修改为:

CMydialog::CMydialog(CWnd* pParent /*=NULL*/) : CDialog(CMydialog::IDD, pParent) { //{{AFX_DATA_INIT(CMydialog) m_ban = FALSE; m_xuesheng = FALSE; m_xueyuan = _T(\ m_num = _T(\ m_info = _T(\ m_name = _T(\ sex=\ other=\ //}}AFX_DATA_INIT }

6.为(复选按钮1)OnCheck1函数添加代码 void CMydialog::OnCheck1() { // TODO: Add your control notification handler code here

other=other+\班干部\}

7.为(复选按钮2)OnCheck2函数添加代码 void CMydialog::OnCheck2() { // TODO: Add your control notification handler code here other=other+\学生会干部\}

8.为(单选按钮1)OnRadio1函数添加代码 void CMydialog::OnRadio1() { // TODO: Add your control notification handler code here sex=\男\}

9.为(单选按钮2)OnRadio2函数添加代码 void CMydialog::OnRadio2()

{ // TODO: Add your control notification handler code here sex=\女\ }

10.为OnOK函数添加代码 // CMydialog message handlers void CMydialog::OnOK()

{ // TODO: Add extra validation here UpdateData(TRUE); m_info=\姓名:\学号:\性别:\学院:\其他:\ UpdateData(FALSE); // CDialog::OnOK(); }

运行程序,选择“显示对话框/显示”命令,就可以看到下面运行的对话框了。

本文来源:https://www.bwwdw.com/article/wsm7.html

Top