您的当前位置:首页正文

VC++ MFC对话框和常用教程

2022-08-18 来源:钮旅网


第五章 对话框和常用控件

对话框是Windows应用程序中最重要的用户界面元素之一,是与用户交互的重要手段,在程序运行过程中,对话框可用于扑捉用户的输入信息或数据。对话框是一个特殊类型的窗口,任何对窗口进行的操作(如:移动、最大化、最小化等)都可在对话框中实施,一般来说,在对话框中通过各种控件(如:按钮、编辑框、列表框、组合框等)来和用户进行交互。控件是在系统内部定义的用于和用户交互的基本单元。 一、对话框的使用

Visual C++提供的对话框编辑器能“可视”地进行设计、编辑,并可用 ClassWizard为对话框从CDialog基类中派生一个类,MFC的CDialog类封装了用于对话框的显示、关闭等操作的许多功能函数,例如:DoModal函数用来显示模式对话框并返回用户操作的结果。

1、模式对话框(为186附加举例页)

所谓模式对话框是指,当对话被弹出时,用户必须在对话框中进行相应的操作,在退出对话框之前,对话框所在的应用程序不能继续执行。平常我们所见到的对话框大多是模式对话框。

例:模式对话框(通过菜单命令弹出) 1) 建一个单文档(SDI)应用程序 2) 创建对话框模板

InsertResource选中Dialog单击New

拖过一个静态文本,鼠标对准它,按右键点properties改标题为“新建模式对话框”。 3)鼠标右键对准对话框的任何位置单击,选择properties选项,设置ID为IDD_MYDIALOG 4)给对话框创建类

双击新建对话框的任何位置,单击OK,写类名为“CMyDlg”,保 证”CDialog”作为该类的基类。 5)创建菜单命令:

a) 打开资源编辑器的菜单项Menu b) 双击IDR_MAINFRAME

c) 双击右边空白菜单,点开pop_up(让它是空白),在名字处写”弹出对话框(&A)”,ID处写ID_PUPDIALOG

6)将菜单命令连接到主框架程序中,完成ID_PUPDIALOG的消息映射: ViewClassWizard保证Class name里是CMainFrame,在ObjectIDs

里找到ID_PUPDIALOG点黑Messages里(右边)点COMMAND建立主框架对象方法并加代码:

void CMainFrame::OnPupdialog() { CMyDlg MyDlg;

MyDlg.DoModal(); //DoModal()是CDialog类成员函数,通过调用该

//函数将显示对话框。

}

7)在CMainFrame.cpp文件里加:

#include “MyDlg.h” // 之后运行。 2、无模式对话框(为186附加页)

非模式对话框,弹出后,可一直保留在屏幕上,用户可继续在应用中进行其它操作或启动其它应用程序,当需要使用对话框时,只需象激活一般窗口一样激活对话框即可。

1)建一个SDI(单文档)应用程序 2)创建对话框模板

InsertResource点黑DialogNew

拖过一个静态文本,鼠标对准它,按右键点properties改标题为“新建非模式对话框”。 3)为对话框创建类

点出对话框(IDD_DIALOG1缺省的ID号),双击对话框中的任意位置,出现一个表,你点OK出现一个对话框,你写类名:CDlg保证基类为CDialog 4)创建菜单

打开工作区MenuIDR_MAINFRAME双击空白菜单写“非模式对话框”关闭再点下面空菜单写名字“显示非模式对话框”ID处写ID_DLG. 5)添加菜单命令消息

WiewClassWizardMessage Maps保证Class name里是Wiew类(视图类),在Object IDS里找到ID_DLG(菜单的ID)点黑右边COMMAND双击它OK 6)a、你在Wiew.h里加:#include “Dlg.h”

b、在public:里加:CDlg *dlg;//创建CDlg对象 c、在View.cpp的OnDlg()函数里加: CMyView::OnDlg() {

dlg=new CDlg(this);

dlg->Create(IDD_DIALOG1);//使对话框摸板从资源中创建一个非

//模式对话框

dlg->ShowWindow(SW_RESTORE);//显示对话框 }

二、使用对话框编辑器(对话框编程)(187页) *1、可建一个单文档应用程序名为“对话框编程”,在此程序中加入一个对话框: InsertResource点黑Dialognew 出现188页的图

2、拖入一些控件,对这些控件进行排序、布局、大小调整、上下对齐、测试等。*最后在对话框IDD_DIALOG1上留一个按钮控件,其标识符为:IDC_BUTTON1 3、识别控件工具栏(188页)

4、在加对话框时,InsertResource点开+Dialog见有7类对话框,分别了解其

不同用途(见192页)。 5、对话框的属性

A、ViewProperties B、按Alt+Enter C、用鼠标右键单击对话框模板Properties 都能弹出对话框的属性框,见书193页对属性General的解释。 *6、为对话框添加类(194页)

对准对话框的任意非控件区域双击鼠标,将弹出书194页图5.11所示 的对话框,询问是否为对话框资源创建一个新类单击OK弹出书194页 图5.12所示的对话框你定义一个新类的名字如:CMyDlg(注意:类名必 须以C打头),下面的基类Base class和ID标识符Dialog ID内容一般不改。 * 7、添映射消息(195页)

接上,点OK出现“MFC ClassWizard”对话框,如书195页图5.13所示(保证类名处是CMyDlg)选定点黑IDC_BUTTON1单击BN_CLICKED消息Add Function出现书195页图5.14对话框OKEdit Code *8、添加用户代码(195页)

接上,到MyDlg.cpp文件中,写: void CMyDlg::OnButton1() {

MessageBox(“欢迎进入对话框的设计!”); }//这时运行还不见对话框,接下 *9、在程序中使用对话框(196页)

由于对话框的代码是以类为模块来设计的,使用时需要在程序中加入该类 的头文件,并定义一个类对象,然后就可以使用该类的相关成员。 项目工作区FileView打开应用程序的.cpp文件,在前面加:

#include “MyDlg.h”

在InitInstance函数体中的return TRUE语句之前添加下列代码: CMyDlg dlg;

dlg.DoModal();//DoModal()函数是负责对话框的显示和终止。 运行!则直接显示出对话框,单击按钮则出现“欢迎进入对话框的设计” 的字样。

本例建的CMyDlg类及以后在各个项目中建立的类,在文档、视图、主框 架类中都可同样使用。 (1)添加对话框资源

对话框资源类型:

IDD_DIALOGBAR 对话条,往往和工具条放在一起。

IDD_FORMVIEW 一个表状风格的对话框,用于无模式对话框或视图类 IDD_OLE_PROPPAGE_LARGE一个大的OLE属性页 IDD_OLE_PROPPAGE_SMALL一个小的OLE属性页

IDD_PROPPAGE_LARGE一个大属性页,用于属性对话框

IDD_PROPPAGE_MEDIUM一个中等大小的属性页,用于属性对话框 IDD_PROPPAGE_SMALL一个小的属性页,用于属性对话框 (2)改变对话框的属性

ID框:修改或选择对话框的标识符名称

Caption框:输入对话框的标题名称,中英文均可。

Font按钮:单击此按钮可选择字体的种类(如宋体)及尺寸(如9号) Xpos/Ypos:对话框左上角在父窗口中的X,Y坐标都为0时表示居中 Menu框:默认值为无,当对话框需要选单时输入或选择指定的选单资源 Class name:默认值为无,它提供C/C++语言编程时所需要的对话框类名,对 MFC类库的资源文件来说,该项不被激活 三、控件的创建和使用方法(197页)

控件是在系统内部定义的能够完成特定功能的控制程序单元。在应用程序中使用控件不仅简化了编程,还能完成常用的各种功能。为了更好地发挥控件的作用,用户还必须理解和掌握控件的属性、消息以及创建和使用方法。 注:控件工具栏及各按钮含义:

1、控件的选择2、静态文本3、组框4、复选框5、组合框6、水平滚动条 7、旋转按钮8、滑动条9、列表视图10、标签11、复合编辑12、月历

13、用户定制工具14、静态图片15、编辑框16、按钮17、单选框18、列表框 19、垂直滚动条20、进展条21、热键22、树形视图23、动画24、日期选择 25、IP地址26、组合框的扩展(从左边往下数,再从右边往下数)

1、控件的创建和使用方法(197页)

控件的创建方法有2种:1)是在对话框摸板中用编辑器指定控件,也就是说,将控件的父窗口指定为对话框,如:上面的BUTTON1按钮控件。2)是将控件看做任意一窗口的子窗口,并通过调用相应的Create函数来创建。下面我们用第2种方法创建控件(此种方法涉及的内容复杂,也不能发挥对话框编辑器可视化编程的优点,故不提倡此种方法,而用第一种方法)。

(1)打开上个项目,在CMyDlg类的头文件MyDlg.h里添加一个按钮类CButton 指针变量:(public:里) CButton *m_btnWnd;

(2)按Ctrl+W或ViewClassWizard打开MFClassWizard对话框,并切换到

Message Maps页面,在Object IDs列表中选定点黑CMyDlg项,并在

Message列表中找到WM_INITDIALOG消息点黑AddFunctionEditCode (3)添加代码:

BOOL CMyDlg::OnInitDialog() { -----

m_btnWnd=new CButton();//构造按钮控件

//下面“”按钮上的字,创建子窗口|窗口最初是可见的|创建的是按键按钮 m_btnWnd->Create(“你好”,WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, CRect(20,20,120,60),this,201);//创建 CFont *font=this->GetFont();//获取对话框的字体 m_btnWnd->SetFont(font);//设置控件字体 return TRUE;//(程序原有的) }

代码中,Create用来创建一个按钮控件,该函数的第一个参数用来指定该按钮的标题,第二个参数用来指定控件的风格,第三个参数用来指定它在父窗口中的位置和大小,第四个参数用来指定父窗口指针,最后一个参数是指定该控件的标识值。 WS_CHILD表示按钮是作为对话框的一个子窗口来创建的。 WS_VISIBLE是使控件可见。

BS_PUSHBUTTON表示创建的是按键按钮。 (4)编译并运行

2、控件的数据交换和数据效验(数据成员)(198页)

使用ClassWizard可以很容易地定义一个控件的成员变量及其数据范围。例如:上面的CMyDlg类的按钮控件IDC_BUTTON1添加并使用其成员变量m_MyBtn,步骤如下: (1)打开上例项目,ViewClassWizardMember Variables选定Class name

中为CMyDlg,然后在Control IDs列表中点黑IDC_BUTTON1AddVariable (或双击鼠标左键),弹出Add Member Variable对话框,如书198页图5.17 写好数据成员名:m_MyBtn 下面Category和Variables type里的不动 OK见表上已建成(如:书199页图5.18) 下面是建成员变量的三个对话框图:

(2)再向对话框加一个编辑控件,并加成员变量m_strEdit,类型为CString置

数值为Value(注:Category框内可选择Value或Control两种类型。Control所对应的变量类型就是MFC为该控件封装的控件类。Value所对应的是数值类型。不同控件所提供的关联的数值类型各不同,例如:对于编辑框来说,Variables type中的数值类型有CString (字符串),int,UINT(32位无符号整数),long(32位带符号整数), DWORD(32位无符号整数,段地址和相关的偏移),float,double,BYTE(8位无符号整数),short,BOOL等)。OK后在下面写20为最大值。(下面见书199—200页)

打开本项目的MyDlg.h见到: CButton m_MyBtn; CString m_strEdit; 在MyDlg.cpp里见到: m_strEdit=_T(“ “);

在DoDataExchange函数体内见:

DDX_Control(pDX,IDC_BUTTON1,m_MyBtn);

DDX_Text(pDX,IDC_EDIT1,m_strEdit);//IDC_EDIT1是标识m_strEdit

//是成员变量

DDV_MaxChars(pDX,m_strEdit,20);//校验m_strEdit的最大字符个数不超过20。 (3)将CMyDlg::OnButton1()修改成: void CMyDlg::OnButton1()

{

UpdateData();//默认参数值是真TRUE m_MyBtn.SetWindowText(m_strEdit);

//GetDlgItem(IDC_BUTTON1)->SetWindowText(“欢迎”);//用此条代替

//上条也行,

//单击Button1按钮,此按钮名就是“欢迎”。

}

之后运行该程序,当在编辑框输入Hello后,单击Button1按钮,则该按 钮的名称就变成了编辑框中的内容Hello了,见书200页。 八、控件的通用属性 (201页)

在控件的属性对话框中含有许多属性,如:书201页(按钮的属性对话

框),General(一般属性)、Styles(控件的风格)、Extended Styles(控件的扩 展风格)。Styles和Extended Styles是用来设定控件的外观的、辅助功能的。 不同控件具有不同的风格和扩展风格。见201页表5.5. 控件的General属性:

ID:控件的标识符,每种控件都有默认的ID,例如按钮控件为IDC_BUTTON1 Caption:控件的标题,大多数控件都有默认的标题,例如按钮控件为Button1 Visible:指定控件初始化时是否可见

Group:指定控件组中的第一个控件,如果该项被选中,则此控件后的所有控件均被看成一

组,成组的目的是可以让用户键盘方向键在同一组控件中进行切换

Help ID:若该项被选中,则为该控件建立一个上下文相关的帮助标识符 Disabled:指定控件初始化时是否禁用

TabStop:若该项被选中,则用户可以使用Tab键来选择控件 九、控件的消息

对于每个消息,系统都会用一个MSG结构来记录(见201页)。对一般控件来说,其通知消息是一条WM_COMMAND消息(见202页)。例:

1、打开上面的项目“对话框”

2、ViewClassWizard在CMyDlg里(左边的Object IDs里点黑CMyDlg) 在Message里找到OnCommand点黑Add FunctionEdit Code写: BOOL CMyDlg::OnCommand(WPARAM wParam,LPARAM lParam) {

WORD nCode=HIWORD(wParam);//控件的通知消息 WORD nID=LOWORD(wParam);//控件的ID号

if((nID==201)&&(nCode==BN_CLICKED))//用户单击按钮产生的消息 MessageBox(\"你按下了\\\"你好\\\"按钮!\"); ----

}//WORD是16位无符号整数

//EN_CHANGE是编辑框中的文本被改变时发出的消息

BN_CLICKED是当用户单击按钮产生的消息:

单击对话框中的“你好”按钮,弹出\"你按下了\\\"你好\\\"按钮!\"的消息对话框。由于Create创建的控件无法用ClassWizard直接映射其消息,因此上述方法祢补了ClassWizard的不足,使用时要特别注意。见书202页通知消息是所有Windows控件所共有的:

NM_CLICK 在控件中单击鼠标左键按钮 NM_DBLCLK 在控件中双击鼠标左键按钮 NM_RDBLCLK在控件中双击鼠标右键按钮

NM_RETURN当控件具有输入焦点时按下ENTER键

NM_SETFOCUS控件得到输入焦点 NM_KILLFOCUS控件失去输入焦点

NM_OUTOFMEMORY没有足够的内存使控件 十、常用控件

静态控件 CStatic 用于向用户显示一些几乎固定不变的文字或图形描述 按 钮 CButton 用于产生某些命令或改变某些选项设置

编辑框 CEdit 可完成文字的输入、输出双向操作,使用户能查看并编辑文字 列表框 CListBox显示一个列表,让用户从中选取一个或多个项

组合框 CComboBox它把列表框和编辑框有机地组合在一起,用户不仅能选择

列表中已有的项,还能编辑出新的项

滚动条 CScrollBar通过滚动块在滚动条上的移动来改变某些数值 进展条 CProgressCtrl 用于指示一个操作的进度 旋转按钮 CSpinButtonCtrl 又称“上下控制”,是一对箭头按钮,用户单击它们

可以增加或减小某个值

滚动条 CSliderCtrl 是一个包含一个滑动块和可选的刻度线,用户可以用鼠标

或方向键沿某个方向移动滑动块

图象列表 CImageList是一系列相同大小的图象的集合

标签控件 CTabCtrl类似于一个笔记本的分割器或一个文件柜上的标签,使用它

可以将一个窗口或对话框的相同区域定义为多个页面

1、静态控件

静态控件是用于显示一个字符、框、矩形、图标、位图或增强的图元文件,它可以用做标签、框或用于分隔其它的控件。一个静态控件一般不接受用户输入,也不产生通知消息。

在对话框编辑器的控件工具栏中,属于静态控件的有:静态文本(Static Text)、

组框(Group Box)、图片控件(Picture)三种。其中,静态图片控件的属性对话框如:书204页图5.21所示,表5.7列出了其一般属性和风格的各个项的意义。我们可以选择Type(图片类型)、Image(图象资源)两个组合框中的有关选项内容,并可将应用程序资源中的图标、位图等内容显示在该静态图片控件中。另外,用户还可设置其风格来改变控件的外观以及图象在控件的位置等。

静态图片控件的General和Style属性对话框:

Type 图片类型,用户可以从中选择Frame(框)、Rectangle(矩形区域)、Icon(图标)、

Bitmap(位图)、Enhanced Metafile(增强图元文件,它是各种绘图命令的集合)

Image 当图片类型为Icon或Bitmap时,通过此框可选择指定的资源ID号 设置Frame和Rectangle的颜色,它可以是black(黑色)、white(白色)、 gray(灰色)、或者是具有3D外观的etched(腐蚀色)

Sunken 选中时,在控件的周围有下沉的边框

Notify 选中时,当用户单击或双击图片时会向其父窗口发出通知消息 Right justify 选中时,用户重置图片大小,图片右下角是固定不变的 Border 选中时,图片周围有边框

Center image 选中时,图片显示在控件中央,其余区域由图片左上角的象素

颜色来填充

Real size image选中时,按图片的原始大小来显示,超过控件区域的部分被裁剪 在它的属性中,用户可以选择Type(图片)、Image(图象资源)两个组合框中的有关选项内容,并可将应用程序资源中的图标、位图等内容显示在该静态图片控件中,另外,用户还可以设置其风格来改变控件的外观以及图象在控件的位置等。 例1:图片控件(将一个.bmp图形显示在图片控件上)(附加举例) 1)建一个单文档(SDI)应用程序

2)创建对话框模板: InsertResource点黑Dialognew

3)将图片控件Picture拖到对话框上,并拉大些,将OK和CANCEL拖到下面。 4)向项目中插入一个 .bmp图片:InsertResource点黑BitmapImport在

出现的表中要下拉出:所有文件(*.*)在某处找到一个.bmp图形Import放到此项目中。

5)将这个图片放到图片控件上

右键对准图片控件单击出现属性框Type处下拉置Bitmapimage处下拉置IDB_BITMAP1,就将图片加到了图片控件上。 6)为刚才建的对话框添加类

双击新建对话框的任何位置OK类名写:CMyDlg 7)创建一个菜单项,用来显示对话框

ResourceViewMenuIDR_MAINFRAME双击空白菜单点POPUP

ID处写:ID_DLG 菜单名写:显示图片对话框关闭 8)将菜单命令映射到View中去

ViewClassWizard要加到View中ID-DLGCOMMANDEditCode (在View.h的头部加:#include “MyDlg.h” 在public:下加:CMyDlg *dlg;)并

加代码:

CMyView::OnDlg()

{ dlg=new CMyDlg(this);

dlg->Create(IDD_DIALOG1); dlg->ShowWindow(SW_RESTORE); } 9)编译运行 2:按钮

常见的按钮有三种类型:(204页) (1)按键按钮

按键按钮通常可以立即产生某个动作,执行某个命令,因此也常被称为命

令按钮。 (2)单选按钮

其外形是在文本前有一个圆圈,当它被选中时,就标上一个黑点。 (3)复选框

其外形是在文本前有一个空心方框,当它被选中时,就加上一个“∨”标记

1)按钮的消息

常见的按钮映射消息有两个: (1) BN_CLICKED(单击按钮)(2)BN_DOUBLE_CLICKED(双击按钮) 见下图:

2)按钮选中操作

最常用的按钮操作是设置或获取一个按钮或多个按钮的选中状态。 CButton类的以下2个成员函数原型如下:

void SetCheck(int nCheck); //设置指定按钮的选中状态 int GetCheck()const; //获取指定按钮的选中状态

其中:nCheck和GetCheck函数返回的值可以是:0表示不选中,1表示选中,

2表示不确定(仅用于三态按钮)

而对于多个单选按钮的选中状态的设置或获取,需要使用CWnd类的成员函数CheckRadioButton和GetCheckedRadioButton,它们的原型如下:

void CheckRadioButton(int nIDFirstButton,int nIDLastButton,int nIDCheckButton); int GetCheckedRadioButton(int nIDFirstButton,int nIDLastButton);

其中,nIDFirstButton和nIDLastButton分别指定这组单选按钮的第一个和最后一个按钮ID值,nIDCheckButton用于指定要设置选中状态的按钮ID值,函数GetCheckedRadioButton返回被选中的按钮ID值。

例2:用静态图片、单选按钮、复选框和按键按钮控件设计界面,运行结果如:书205页图5.23所示。刚开始,所有单选按钮都是灰显的,我们不能选择它们,这种情况称为“禁用”,而当选中“允许”复选框后,所有单选按钮可以使用,用户选定一个单选框后,单击[应用]按钮,则弹出相应的消息对话框。

(1)用MFC AppWizard(exe)创建一个名为:“按钮的使用”的基于对话框的应用

程序。(第一步将类型选择为Dialog Based,然后按[Finish]按钮即可。) (2)打开属性对话框,将其标题改为“使用Windows常用控件”。

(3)参看书205页图5.23的控件布局,用编辑器为对话框添加如书206页表5.8

所示的一些控件。

(4)说明:上面4个单选按钮的Tab次序应连续,而且从IDC_RADIO1到IDC_RADIO4

依次增加。

(5)ViewClassWizard(或按Ctrl+W快捷键)切换到Member Variables页面,在Class

name中选择CMyDlg,在Control IDs里选中点黑IDC_CHECK1复选框ID号Add Variables按钮,为其添加一个BOOL类型的成员变量 m_bEnabledOK。

(6)切换到ClassWizard的Message Maps页面,分别选中点黑复选框IDC_CHECK1和按

钮IDC_BUTTON1,分别为其添加映射消息,并添如下代码: void CMyDlg::OnCheck1() {

UpdateData();

for(int i=0;i<4;i++)

GetDlgItem(IDC_RADIO1+i)->EnableWindow(m_bEnabled);

}//EnableWindow是使一个控件窗口禁用或允许使用,它取决于该函数 //的参数,为TRUE时表示可以使用,否则禁用。 void CMyDlg::OnButton1()

{

UpdateData();

if(!m_bEnabled) return;

int nID=GetCheckedRadioButton(IDC_RADIO1,IDC_RADIO4); if(nID==IDC_RADIO1) { MessageBox(“1”); } if(nID==IDC_RADIO2) { MessageBox(“2”); } if(nID==IDC_RADIO3) { MessageBox(“3”); } if(nID==IDC_RADIO4) { MessageBox(“4”); }

(7)在此文件中找到CMyDlg::OnInitDialog函数体,添加下列代码: BOOL CMyDlg::OnInitDialog() {

CheckRadioButton(IDC_RADIO1,IDC_RADIO4,IDC_RADIO1); //设置第一个单选按钮为选中 OnCheck1();

return TRUE;//此条是原有的 (8)编译运行 3、编辑框

编辑框是一个让用户从键盘输入和编辑文本的矩形窗口,用户可以通过它,很方便地输入各种文本、数字或口令,也可使用它来编辑和修改简单的文本内容。 当编辑框被激活且具有输入焦点时,就会出现一个闪动的插入符(又可称为文本光标),表明当前插入点的位置。 1)编辑框的属性和风格

Align text 各行文本对齐方式:Left,Center,Right,默认时为Left Multiline 选中时为多行编辑框,否则为单行编辑框 Number 选中时控件只能输入数字

Horizontal scroll 水平滚动,仅对多行编辑框有效

Auto HScroll当用户在行尾键入一个字符时,文本自动向右滚动 Vertical scroll 垂直滚动,仅对多行编辑框有效

Auto VScroll 当用户在最后一行按ENTER键时,文本自动向上滚动一页,仅对

多行编辑框有效

Password 选中时,键入编辑框的字符都将显示为”*”,用于口令设置,仅对

单行编辑框有效

No hide selection通常情况下,当编辑框失去键盘焦点时,被选择的文本仍然反

色显示,选中时,则不必具备此功能

OEM convert 选中时,实现对特定字符集的字符转换

Want return 选中时,用户按下ENTER键,编辑框中就会插入一个回车符 Border 选中时,在控件的周围存在边框

Uppercase 选中时,键入在编辑框的字符全部转换成大写形式 Lowercase 选中时,键入在编辑框的字符全部转换成小写形式 Read-Only 选中时,防止用户键入或编辑文本

多行编辑框具有简单文本编辑器的常用功能,例如:它可以有滚动条,用户按Enter键另起一行以及文本的选定、复制、粘贴等常见操作。而单行编辑框功能较简单,它仅用于单行文本的显示和操作 2)编辑框的基本操作 A、设置口令

口令设置在编辑框中不同于一般的文本编辑框,用户输入的每个字符都被一个特殊的字符代替显示。这个特殊的字符称为口令字符。默认的口令字符是”*”。

应用程序可以用成员函数CEdit::SetPasswordChar 来定义自己的口令字符,其函数原形如下:

void SetPasswordChar(TCHAR ch);

其中,参数ch表示设定的口令字符;当ch=0时,编辑框内将显示实际字符。 B、选择文本

编程选择文本,调用成员函数CEdit::SetSel来实现,还有:

CEdit::GetSel和CEdit::ReplaceSel,它们分别用来获取编辑框中选择的开始和结束的位置以及替换被选择的文本。 C、设置编辑框的页面边距

用CEdit::SetMargins函数来实现,其函数原型如下: void SetMargins(UINT nLeft,UINT nRight);

其中,参数nLeft和nRight分别用来指定左、右边距的象素大小。 D、剪帖板操作

E、获取多行编辑框文本(见书208页---209页)。 如何设置口令(密码):附加例题见后面(教案页) 3)编辑框的通知消息

当编辑框的文本修改或者被滚动时,会向其父窗口发送一些消息,这些消息 是:(参看书209页表5.10并由下图所示:)

EN_CHANGE当编辑框中的文本已被修改,在新的文本显示之后发送此消息 EN_HSCROLL当编辑框的水平滚动条被使用,在更新显示之前发送此消息 EN_KILLFOCUS编辑框失去键盘输入焦点时发送此消息 EN_MAXTEXT文本数目到达了限定值时发送此消息 EN_SETFOCUS编辑框得到键盘输入焦点时发送此消息

EN_UPDATE编辑框中的文本已被修改,新的文本显示之前发送此消息 EN_VSCROLL当编辑框的垂直滚动条被使用,在更新显示之前发送此消息

例:使用静态文本、组框、编辑框以及按钮等控件设计界面,运行结果参书209

页图5.25即下图所示。当用户在“成绩1”、“成绩2”、和“成绩3”编辑框中输 入成绩后,单击[计算平均分]按钮,将显示出这三个成绩的平均分。

程序设计步骤如下:

(1) 打开前面的项目“按钮的使用”。

(2) 向应用程序中添加一个对话框资源,insertResource点黑Dialognew

出现一个新的对话框右键单击这个新对话框properties打开其属

性对话框Font将其字体设置为“新宋体,9”,标题改为“使用编辑框”, ID号改为IDD_EDIT,删除默认的Cancel按钮。 (3)、(4)、(5)按书210页往下作

书(6)m_strAve=\"0.00\"; UpdateData(FALSE);//将成员变量数据传给控件,并在控件中显示 书(7)UpdateData();//将控件显示的数据传给成员变量 double ave=(double)(m_nScore1+m_nScore2+m_nScore3)/3.0; m_strAve.Format(\"%6.2f\是CString类的一个经常使用的成

//员函数,它通过格式操作使任意类型的数据转换成一个字符串

UpdateData(FALSE);//将成员变量数据传给控件,并在控件中显示 书(8)定位到void CMyDlg::OnButton1()

{ ---------//注意,这是你上个程序的按钮命令,在里找到: if(nID= =IDC_RADIO1)

{ CEditDlg dlg; //注意,将原来MessageBox(\"1\");去掉 dlg.DoModal(); //加上这2条 }

书(9)在上个程序的:按钮的使用Dlg.cpp即CMyDlg.cpp的头文件处加: #include \"EditDlg.h\"(就是(8)所在的文件) 编译运行 4、列表框

列表框是一个列有许多项目让用户选择的控件。它与单选按钮组或复选框组一样,都可让用户在其中选择一个或多个项。但不同的是,列表框中项的数目是可灵活变化的,程序运行时可往列表框中添加或删除某些项。并且,当列表框中项的数目较多而不能一次全部显示时,还可以自动提供滚动条来让用户浏览其余的列表项。 1)列表框的风格

按性质来分,列表框有单选、多选、扩展多选以及非选四种类型,默认风格

下的单选列表框让用户一次只能选择一个项,多列表框可让用户一次选择几个项,而扩展多项列表框允许用户用鼠标拖动或其它特殊组合键进行选择,非选列表框不提供选择功能。还有其它一系列风格,用于定义列表框的外观及操作方式,这些风格可在下图所示的列表框属性对话框中设置:列表框的Styl属性:

Selection指定列表框的类型:单选(Single)、多选(Multiple)、扩展多选(Extended)、不选(None) Owner draw自画列表框,默认为No

Has strings选中时,在自画列表框的项目中含有字符串文本 Border选中时,使列表框含有边框

Sort选中时,列表框的项目按字母顺序排列

Notify选中时,当用户对列表框操作就会向父窗口发送通知消息 Multi-column选中时,指定一个具有水平滚动的多列列表框 Horizontal scroll选中时,在列表框中创建一个水平滚动条 Vertical scroll选中时,在列表框中创建一个垂直滚动条 No redraw选中时,列表框发生变化后不会自动重画

Use tabstops选中时,允许使用停止位来调整列表项的水平位置

Want key input选中此项,当用户按键且列表框有输入焦点时,就会向列表框的父窗口发送

相应消息

Disable no scroll选中时,即使列表框的列表项能全部显示,垂直滚动条也会显示,但此时

是禁用的(灰显)

No integral height选中时,在创建列表框的过程中,系统会把用户指定的尺寸完全作为列表

框的尺寸,而不论是否有项目在列表框,也不能完全显示出来

2) 列表框的基本操作

当列表框创建之后,往往要添加、删除、改变或获取列表框中的列表项,这些操作都可以调用MFC的CListBox类成员函数加以实现。

索引:表明项目在列表框中排列的位置,它是以0为基数的,即列表框中第一项的索引是0,第二项的索引是1,依次类推。 (1)添加列表项

列表框创建时是一个空的列表,需要用户添加或插入一些列表项,其函数原型为: int AddString(LPCTSTR lpszItem); int InsertString(int nIndex,LPCTSTR lpszItem);

其中:列表项的字符串文本由参数pszItem来指定,成功返回列表在列表框的索引,错

误返回LB_ERR,空间不够返回LB_ERRSPACE。

但:InsertString函数不会将列表项进行排序,不论列表框控件是否具有sort属性,只是将列表项插在指定索引的列表项之前,若nIndex等于-1,则列表项添加在列表框末尾。 而:AddString函数在当列表框控件具有sort属性时会自动将添加的列表项进行排序。

以上2个函数只能将字符串增加到列表框中,但有时用户还会需要根据列表项使用其他数据。这时,ListBox的SetItemData和SetItemDataPtr能有效解决这个问题,它们能使用户数据和某个列表项关联起来:

int SetItemData(int nIndex,DWORD dwItemData); int SetItemDataPtr(int nIndex,void *pData);

其中,SetItemData是将一个32位数与某列表项(由nIndex指定)关联起来,而 SetItemDataPtr可以将用户的数组、结构体等大量的数据与列表项关联 若产生错误,它们都返回LB_ERR

而:GetItemData和GetItemDataPar分别用来获取相关联的用户数据。

以下等待修改

(2)删除列表项(3)查找列表项(4)列表框的单项选择 (5)列表框的多项选择 3)列表框的通知消息

当列表框中发生了某个动作,如用户双击选择了列表框中某仪项时,列表框就会向父窗口发送一条通知消息。常用的通知消息如书214页表5.14所示。

例:将一个SCORE结构(含有三门成绩的数据成员)数据和列表中每一个学生

姓名列表关联起来。当用户单击[添加记录]按钮时,学生成绩记录中的“姓 名“被添加在列表框中,且该学生的成绩与该列表项关联。当用户单击[删 除记录]按钮时,列表框中当前选择项被删除,相关联的数据所占的内存空 间被释放。任何时候选中列表框中某个学生,相应的记录数据被显示出来, 如:书214页图5.27所示。

(1) 打开前面的基于对话框的项目“按钮的使用”。

(2) 向项目中添加一个对话框资源IDD_LISTBOX,标题为“使用列表框”,并用

ClassWizard为此对话框建类为:CListBoxDlg。

接着按书214页往下作:(3)、(4)-------

(可在此处将第9步、第11步作出…………. 因为第5步要用到SCORE结构体 ) 书(5)

UpdateData(TRUE); if(m_strName.IsEmpty())//判断m_strName是否为空 { MessageBox(\"姓名不能为空!\"); return; } m_strName.TrimLeft();//裁剪m_strName左边的空格 m_strName.TrimRight();//裁剪m_strName右边的空格 if((m_List.FindString(-1,m_strName))!=LB_ERR) { MessageBox(\"列表框中已有相同姓名,不能添加!\"); return; } int nIndex=m_List.AddString(m_strName);//向列表框添加学生 //姓名将该学生成绩与新增的列表项关联起来 SCORE data; data.score1=m_nScore1; data.score2=m_nScore2; data.score3=m_nScore3; m_List.SetItemDataPtr(nIndex,new SCORE(data)); 书(6)

int nIndex=m_List.GetCurSel();//获得当前选项的索引 if(nIndex!=LB_ERR) { m_List.DeleteString(nIndex);//删除当前选择项 m_strName.Empty(); m_nScore1=m_nScore2=m_nScore3=0; UpdateData(FALSE); } else MessageBox(\"当前没有选择项或列表框操作失败!\"); 书(7)

int nIndex=m_List.GetCurSel(); if(nIndex!=LB_ERR) { m_List.GetText(nIndex,m_strName); SCORE *data=(SCORE *)m_List.GetItemDataPtr(nIndex); m_nScore1=data->score1; m_nScore2=data->score2; m_nScore3=data->score3; UpdateData(FALSE); } 书(8)

for(int nIndex=m_List.GetCount()-1;nIndex>=0;nIndex--) { //删除所有与列表相关联的SCORE结构数据,并释放内存 delete(SCORE *)m_List.GetItemDataPtr(nIndex); }

CDialog::OnDestroy();//关闭对话框

说明:对话框被清除时发送WM_DESTROY消息。用户在此消息的映射函数中添加一些对象删除代码,以便在对话框清除前有效地释放内存空间。 书(9)

struct SCORE { int score1; int score2; int score3; };

书(10)定位到void CMyDlg::OnButton1()

{ ---------//注意,这是你上个程序的按钮命令,在里找到: if(nID= =IDC_RADIO2)

{ CListBoxDlg dlg; //注意,将原来MessageBox(\"2\");去掉 dlg.DoModal(); //加上这2条 }

}

书(11)在上个程序的:按钮的使用Dlg.cpp即CMyDlg.cpp的头文件处加: #include \"ListBoxDlg.h\"

//(就是(10)所在的文件) 编译运行

注意:第4步完后,可以先将第9步和第11步作出,以能点出相应函数。

5、组合框

列表框中不能输入列表项之外的内容,而编辑框也没有列表框的选择操

作。于是就把常用的项,列在列表框中以供选择,而同时提供编辑框,允许 用户输入列表框中所没有的新项,这就是组合框控件。它结合列表框和编辑 框的特点,取二者之长,从而完成较为复杂的输入功能。 1) 组合框的风格及类型

按照组合框的主要风格特征,可分为三类:简单组合框、下拉式组合框、

下拉式列表框。简单组合框和下拉式组合框都包含列表框和编辑框,但是简单组合框中的列表框不需要下拉,是直接显示出来的,而当用户单击下拉式组合框中的下拉按钮时,下拉的列表框才被显示出来。下拉式列表框虽然具有下拉式的列表,却没有文字编辑功能。

组合框的一些其它风格,见书217页图5.28所示的组合框的属性对话框

中的设置。其各项含义见书218页表5.17所示。 2) 组合框常见操作

组合框的操作大致分为两类,一类是对组合框中的列表框进行操作, 另一类是对组合框中的编辑框进行操作。这些操作都可以调用CComboBox 成员函数来实现,见书218页表5.18所示。由于组合框的一些编辑操作与 编辑框CEdit的成员函数相似,如:GetEditSet,SetEditSel等,因此这些 成员函数没有在上述表中列出。 3) 组合框的通知消息

在组合框的通知消息中,有的是操作列表列表框发出的,有的是操作 编辑框发出的,如:书219页表5.19所示。

例:根据用户从组合框中选择的填充样式,在对话框中绘制一个矩形区域, 如:书

220页图5.29所示。由于对话框是一个窗口,所以用户可以调用GDI绘图函数在对话框内的任何部分进行绘图,至于绘图时需要的一些技巧见书220页的说明:(1)、(2)、(3)。本例操作步骤如下:

(1)打开前面创建的基于对话框应用程序“按钮的使用”。

(2)向应用程序中添加一个对话框资源IDD_COMBO,标题为“使用组合框”,如:书220

页图5.30所示。并用ClassWizard为新加的对话框定义类,名为:CComboDlg。 (3)、(4)、(5)按书220--221页整个操作步骤做完。 书(6)

int nIndex=m_Pattern.GetCurSel();//获得当前选项的索引 if(nIndex!=CB_ERR) { m_nDrawPattern=m_Pattern.GetItemData(nIndex);//获得与当 //前选项相关联的数据 Invalidate();//强制系统调用OnPaint函数重新绘制 } 书(7)

CWnd *pWnd=GetDlgItem(IDC_DRAW);//获得控件IDC_DRAW的窗口指针 pWnd->UpdateWindow();//避免系统自动重绘 CDC *pDC=pWnd->GetDC();//获得所需要的绘图设备环境 CBrush drawBrush;//定义一个画刷 drawBrush.CreateHatchBrush(m_nDrawPattern,RGB(0,0,0));//创建画刷 CBrush *pOldBrush=pDC->SelectObject(&drawBrush);//将画刷选入当前设

//备环境中

CRect rcClient;//定义一个CRect变量 pWnd->GetClientRect(rcClient);//获得窗口客户区大小 pDC->Rectangle(rcClient);//用当前画刷绘制一个矩形区域 pDC->SelectObject(pOldBrush);//恢复设备环境原来的画刷设置 书(8)

CDialog::OnInitDialog(); CString str[6]={\"水平线\竖直线\向下斜线\向上斜线\ \"十字线\交叉线\ int nIndex; for(int i=0;i<6;i++) { nIndex=m_Pattern.AddString(str[i]); m_Pattern.SetItemData(nIndex,i); } m_Pattern.SetCurSel(0); m_nDrawPattern=0; 书(9)

CComboDlg dlg; dlg.DoModal();

书(10)#include “ComboDlg.h”

-------------------------

6、滚动条和进展条

进展条通常用来说明操作的进度,并在操作完成时从左到右充填进展条, 这个过程可以让用户看到还有多少任务要完成。滚动条也是一种控件,它能 完成诸如定位之类的操作。 1) 滚动条

滚动条是一个独立的窗口,虽然它具有直接的输入焦点,但却不能自动地滚动窗口的内容,因此,它的使用受到一定的限制。根据滚动条的走向,可分为垂直滚动条和水平滚动条两种类型。

(1)滚动条的基本操作:滚动条的基本操作一般包括设置和获取滚动条的范围及滚动块的相应位置。由于滚动条控件的默认滚动范围是0---0,因此如果不设置滚动条范围,那麽滚动条中的滚动块就滚动不起来。

在MFC的CScrollBar类中,函数SetScrollRange是用来设置滚动条范围的,其原型如下:

SetScrollRange(int nMinPos,int nMaxPos,BOOL bRedraw=TRUE);

其中:nMinPos和nMaxPos表示滚动位置的最小值和最大值。bRedraw 为重画标志,当为TRUE时,滚动条被重画。在CScrollBar类中,设置滚 动块位置操作是由SetScrollPos函数来完成的,其原型如下:

int SetScrollPos(int nPos,BOOL bRedraw=TRUE);

其中:nPos表示滚动块的新位置,它必须是在滚动范围之内。获取滚动条 的当前范围以及当前滚动位置的两个函数原型是:

void GetScrollRange(LPINT lpMinPos,LPINT lpMaxPos); int GetScrollPos();

需要说明的是:在CScorllBar类的成员函数中,还可以用SetScrollInfo 和GetScrollInfo来代替上面提到的4个函数。与前面的函数相比,使用 SetScrollInfo函数还能使滚动块的大小随内容的多少而改变,并且这两个函

数都使用下面的SCROLLINFO结构:见书223页这个结构体的描述:

(2)当用户对滚动条进行操作时,滚动条就会向父窗口发送WM_HSCROLL(水平滚动条)或WM_VSCROLL(垂直滚动条)消息。这些消息是通过ClassWziard在其对话框(滚动条的父窗口)中进行映射的,并产生相应的消息映射函数OnHScroll和OnVScroll,这两个函数原型如下:

afx_msg void OnHScroll(UINT nSBCode,UINT nPos,CScrollBar *pScrollBar); afx_msg void OnVScroll(UINT nSBCode,UINT nPos,CScrollBar *pScrollBar); 其中:nPos表示滚动块的当前位置,pScrollBar表示由滚动条控件的指针,

nSBCode表示滚动条的通知消息。见书223页表5.21所示。 2) 进展条

进展条是一个如书224页图5.33所示的控件。除了能表示一个过程的进展情况外,使用进展条还可以表明温度、水平面或类似的测量值。进展条的设置范围、当前位置、设置增量等,都是通过:CProgressCtrl类的成员函数实现的。

int SetPos(int nPos); int GetPos();

这两个函数分别用来设置和获取进展条的当前位置,需要说明的是,这个当前位置是指在SetRange中的上限和下限范围之间的位置。

voit SetRange(short nLower,short nUpper); void SetRange32(int nLower,int nUpper); void GetRange(int &nLower,int &nUpper);

它们分别用于设置和获取进展条范围的上限和下限值,一旦设置后,还会重画 此进展条来反映新的范围,成员函数SetRange32为进展条设置32位的范围。 参数:nLower和nUpper分别表示范围的下限(默认值为0)和上限(默认值

为100)。

int SetStep(int nStep);

该函数用于设置进展条的步长并返回原来的步长,默认步长为10。 int SetpIt();

该函数将当前位置向前移动一个步长并重画进展条,以反映新的位置,函数 返回进展条上一次的位置。 7、 旋转按钮控件和滑动条

“旋转按钮控件”(也称为上下控件)是一对箭头按钮,用户单击它们来增加 或减小某个值,比如一个滚动位置或显示在相应控件中的一个数字。 一个“滑动条控件”(也称为跟踪器)是一个包含一个滑动块和可选的刻度线的窗口。这两个控件的说明见书225页。 1)旋转按钮控件

(1)旋转按钮控件常用的风格

见书225页图5.36所示,其中各项含义见书225页表5.22所示

(2)旋转按钮控件的基本操作

MFC的CSpinButtonCtrl类提供了旋转按钮控件的各种操作函数,使用

它们用户可以进行基数、范围、位置设置和获取等基本操作。成员函数: SetBase是用于设置基数的,这个基数值决定了伙伴窗口显示的数字是十进 制的还是十六进制的。函数原型如下: int SetBase(int nBase);// 是用于设置基数的

其中参数nBase表示控件的新的基数。与此函数相对应的成员函数GetBase

是获取旋转按钮控件的基数。

int SetPos(int nPos);//设置旋转按钮控件的当前位置

int SetRange(int nLower,int nUpper);// 设置旋转按钮控件的当前范围。

参数:nPos表示控件的新位置,它必须在控件的上限和下限指定的范围之内。

nLower和nUpper表示控件的上限和下限,任何一个界限值都不能大于Ox7fff或小

于-Ox7fff.

函数GetPos()和GetRange()分别用于获取旋转按钮控件的当前位置和范围成员函数:SetAccel()和GetAccel()分别用于设置和获取旋转按钮控件的加速度。其中函数SetAccel的原型如下:

BOOL SetAccel(int nAccel,UDACCEL *pAccel);

参数:nAccel表示由pAccel指定的UDACCEL结构的数目,pAccel指向一 个UDACCEL结构数组的指针,该数组包含加速信息。见书226页说明。

(3)旋转按钮的通知消息是:UDN_DELTAPOS它是当控件的当前数值将要改 变时向其父窗口发送的。 3)滑动条

滑动条控件是由滑动块和可选的刻度线组成的。当用户用鼠标或方向键移动滑动块时,该控件发送通知消息来表明这些改变。见书226—227页说明。 (1)滑动条的风格

见书227页图5.38所示,其中各项含义见书227页表5.23所示。 (2)滑动条的基本操作

MFC的CSliderCtrl类提供了滑动条控件的各种操作函数,这其中包括范围、位置设置和获取等。

void SetPos(int nPos);//设置滑动条的位置

void SetRange(int nMin,int nMax,BOOL bRedraw=FALSE);// 设置滑动条的范围 void GetPos();//获取滑动条的位置 void GetRange();//获取滑动条的范围

BOOL SetTic(int nTic);//设置滑动条控件中的一个刻度线的位置

void SetTicFreq(int nFreq);//设置显示在滑动条中的刻度线的疏密程度 void ClearTics(BOOL bRedraw=FALSE); void SetSelection(int nMin,int nMax); 参数:nPos表示新的滑动条位置

bMin和nMax表示滑动条的最小和最大位置

bRedraw表示重画标志,为TRUE时,滑动条被重画。 nTic表示刻度线的位置

nFreq表示刻度线的疏密程度,如果参数设置为2,则在滑动条的范围中, 每两个增量显示一个刻度线,要使这个函数有效,必须在属性对话

框中选中Auto ticks项。

bRedraw表示重画标志,若该参数为TRUE,则在选择被清除后,重画滑

动条

nMin和nMax表示滑动条的开始和结束位置 (3) 滑动条的通知消息

滑动条的通知消息代码常见的有: TB_BOTTOM,TB_ENDTRACK,

TB_LINE_DOWN,TB_LINEUP,TB_PAGEDOWN,TB_PAGEUP,

TB_THUMBPOSITION,TB_THUMBTRACK和TB_TOP等。这些消息代码都来自于WM_HSCROLL或WM_VSCROLL消息,其具体含义同滚动条。

例:用滚动条、滑动条和旋转按钮控件分别来调整RGB的三种颜色分量:R (红色分量)、G(绿色分量)和B(蓝色分量),并根据用户指定的颜色填充 一个矩形区域,如书228页图5.39所示:

操作步骤如下:

(1)打开前面创建的基于对话框的应用程序“按钮的使用”。 (2)、(3)、(4)、(注意:在这可先将第(9)、(10)步作出,因第5步要用m_bEditOK

和Draw)按书228---231页做完

书(5)

if(!m_bEditOK) return; UpdateData(); m_Scroll.SetScrollPos(m_RValue); m_Slider.SetPos(m_GValue); Draw(); 书(6)

CWnd *pWnd=GetDlgItem(IDC_DRAW); pWnd->UpdateWindow(); Draw(); 书(7) //设置滚动条和滑动条的范围和当前位置 m_Scroll.SetScrollRange(0,255); m_Scroll.SetScrollPos(m_RValue); m_Slider.SetRange(0,255); m_Slider.SetPos(m_GValue); //设置旋转按钮的范围 m_Spin.SetRange(0,255); UpdateData(FALSE);//将数据传给控件 m_bEditOK=TRUE; 书(8)

int nID=pScrollBar->GetDlgCtrlID(); if(nID==IDC_SLIDER1)//是滑动条产生水平滚动消息 { m_GValue=m_Slider.GetPos(); }//获得滑动条当前的位置 if(nID==IDC_SCROLLBAR1)//是滚动条产生水平滚动消息 { switch(nSBCode) {

case SB_LINELEFT:m_RValue--;//单击滚动条左边箭头 break; case SB_LINERIGHT:m_RValue++;//单击滚动条右边箭头 break; case SB_PAGELEFT:m_RValue-=10; break; case SB_PAGERIGHT:m_RValue+=10;

break;

case SB_THUMBTRACK:m_RValue=nPos; break; } if(m_RValue<0) m_RValue=0; if(m_RValue>255)m_RValue=255; m_Scroll.SetScrollPos(m_RValue); } UpdateData(FALSE); Draw();

书(9)第4步将Draw()函数加上了,在这里添加代码: CWnd *pWnd=GetDlgItem(IDC_DRAW); CDC *pDC=pWnd->GetDC();//获得窗口当前的设备环境指针 CBrush drawBrush;//定义画刷变量 drawBrush.CreateSolidBrush(RGB(m_RValue,m_GValue,m_BValue)); //以上创建一个填充颜色画刷,RGB是一个颜色宏,用来将指定的红、 //绿、蓝三种颜色分量转换成一个32位的RGB颜色值 CBrush *pOldBrush=pDC->SelectObject(&drawBrush); CRect rcClient; pWnd->GetClientRect(rcClient); pDC->Rectangle(rcClient); pDC->SelectObject(pOldBrush);

书(10)第4步已作了,别忘了在CScrollDlg.cpp的构造函数例将m_bEditOK 设为:FALSE

书(11)还是定位到原始程序的OnButton1函数处,改MessageBox(\"4\")代码为:

CScrollDlg dlg;

dlg.DoModal();

书(12)在按钮的使用Dlg.cpp的开头处加:#include “ScrollDlg.h” 书(13)编译运行

附:设置口令(附加举例)

(1)建一个多文档应用程序(选MultipleDocuments后,直接按Finish)

(2)插入一个对话框ResourseView点中Dialog单击右键InsertDialog出现对话框 (3)将这个对话框的ID改为IDD_PASSWORD_DIALOG,名字处写:口令 (4)将OK和CANCEL改为确定和取消(并拖到最下边)

(5)拖一个静态文本StaticText写请输入口令,并拖一个编辑控件Edit Box 改ID为:IDC_PASSWORD_EDIT,在Styles中选PassWord属性。 (6)再加一个静态文本StaticText写:口令为0----9999之间的一个整数。

在风格ExtendedStyles中置Client edge、Static edge、Modal frame。 (7)可测试一下对话框布局 (8)创建对话框类:

双击对话框任意位置OK出见类表你写类名为:CPassWordDialog (9)加成员变量:

ViewClassWizardMemberVariables(classname中是CPassWordDialog 点中IDC_PASSWORD_EDITAddVariable名字写:m_password,TYPE

类型写:int OK后回来处,在下面的Minimumvalue处写:0 Maximumvalue处写:9999。

(10)在应用程序的InitInstance()函数中加代码: Bool CMyApp::InitInstance() { -----

CPassWordDialog CDlg;

if(CDlg.DoModal()==IDOK) //用户按了确定按钮 {

if(CDlg.m_password!=1949) //口令为整数1949 {

AfxMessageBox(“口令错误,确定后将退出程序”); return FALSE; } }

else //如果按下取消按钮程序也结束 return FALSE; return TRUE; }

(11)在文件“设置口令.cpp“头部加: #include “PassWordDialog.h” (12)编译、运行

---------------------

8、图像列表和标签控件

“图像列表”是一系列相同大小的图像的集合,每一个图像提供一个以0为基数的索引号。而一个“标签控件”类似于一个笔记本中的分割器,或一个文件上的标签。 1)图象列表控件

图象列表控件常用来有效地管理多个位图和图标。在MFC中,图象列表控件是使用CImageList类来创建、显示或管理图象的。

(1)创建一个图象列表首先要声明一个CImageList对象,然后调用Create 函数。由于Create函数的重载很多,故这里只给出最常用的一个原型: BOOL Create(int cx,int cy,UINT nFlags,int nInitial,int nGrow); 参数:cx和cy用于指定图象的像素大小;

nFlags表示要创建的图象类型,一般取其ILC_COLOR和ILC_MASK(指定屏蔽图像)的组合,默认的ILC_COLOR为ILC_COLOR4(16色),ILC_COLOR8(256色)ILC_COLOR16(16位色)等。

nInitial用于指定图像列表中最初的图像数目

nGrow表示当图像列表的大小发生改变时,图像可以增加的数目。 (2)图像列表常见的基本操作:

int Add(CBitmap *pbmImage,CBitmap *pbmMask); int Add(CBitmap *pbmImage,COLORREF crMask); int Add(HICON hIcon);

如上函数用来向一个图像列表添加一个图标或多个位图,成功时返回第一个新图像的索引号,否则返回-1。

参数:pbmImage表示包含图像的位图指针 pbmMask表示包含屏蔽的位图指针 crMask表示屏蔽色 hIcon表示图标句柄

BOOL Remove(int nImage);//用于从图像列表中删除一个由nImage指定的图像

BOOL Drew(CDC *pdc,int nImage,POINT pt,UINT nStyle);//用于在由pt指定的位//置处绘制一个图像

参数:pdc表示绘制的设备环境指针 nImage表示要绘制的图像的索引号 nStyle用于指定绘制图像时采用的方式

HICON ExtractIcon(int nImage);//用于将nImage指定的图像扩展为图标 COLORREF SetBkColor(COLORREF cr);//设置图像列表的背景色,COLORREF是一种专门用于定义颜色的数据类型。 2)标签控件

通过使用标签控件,应用程序可以将一个窗口或对话框的相同区域定义为多个页面。每一页包含一套信息或一组控件。当用户选择了相应的标签时,应用程序就会显示相应的信息或控件。一种特殊类型的标签控件把标签显示得象按钮一样。单击一个按钮将立即执行一条命令而不是显示一个页,这也是标签控件与属性页的最根本区别。 (1)标签控件的风格

见书232页图5.40所示,书233页表5.26列出该属性对话框的各项含义。 (2)标签控件的基本操作

MFC的CTabCtrl类提供了标签控件的各种操作函数。 CSize SetItemSize(CSize size);//设置某个项的宽度和高度 void SetPadding(CSize size);//设置标签和标签周围的间隔 int SetMinTabWidth(int cx);//设置标签项的最小宽度

BOOL GetItemRect(int nItem,LPRECT lpRect)const;//获取标签的边界大小 BOOL InsertItem(int nItem,LPCTSTR lpszItem);//

BOOL InsertItem(int nItem,LPCTSTR lpszItem,int nImage);

//如上函数表示在一个标签控件中插入某一标签项

BOOL DeleteItem(int nItem);// 表示在一个标签控件中删除某一标签项 BOOL DeleteAllItem();//表示在一个标签控件中删除所有标签项 参数:nItem用于指定一个标签索引(0表示第一个标签) lpszItem用于指定标签文本

nImage用于指定标签的图标在图像列表中的图像索引。 说明:在标签控件中使用图像列表时,必须调用:

CTabCtrl::SetImageList()函数来指定一个已创建的图像列表,函数

原型如下:

CImageList *SetImageList(CImageList *pImageList);

参数:pImageList用于表示一个图像列表指针 int SetCurSel(int nItem);//设置当前选择的标签 int GetCurSel()const;//获取当前选择的标签

参数:nItem用于表示当前选择项的索引

void DeselectAll(BOOL fExcludeFocus);//重新设置一个标签控件中的

//项,清除任何被按下的项

BOOL HighlightItem(int idItem,BOOL fHighlight=TRUE);//使某一个标签

//项处于高亮状态

参数:fExcludeFocus用于指定一个重排标志 idItem用于指定一个标签的索引 fHighlight指定要设置的高亮状态 (3)标签控件的通知消息。

常见的标签通知消息有:

TCN_KEYDOWN //表示用户按下某键 TCN_SELCHANGE//表示标签选项已被改变

和TCN_SELCHANGING//当前标签选项将要改变

例: 使用无模式对话框来构造某个标签页面,一开始将所有的标签页面创建好,然后根据所选择的当前标签选项,决定哪个页面需要显示,哪个页面需要隐藏和禁用。

操作步骤如下:

(1)用MFC AppWizard(exe)创建一个基于对话框的应用程序“图像列表和标签控件”。按

书234---237页做完。 (2)、(3)、(4)、(5)、(6)、(7)、(8)、(9)注意:第9步的工作已经在第8 步自动加完了,这里就不做什么了。

书(10)切到ClassView右键对准CScrollDlg击出对话框后,加函数时要这样加: 类型:void 函数名:SetDlgState(CWnd *pWnd,BOOL bShow) 类型:void 函数名:DoTab(int nTab)

void CMyDlg::SetDlgState(CWnd *pWnd,BOOL bShow) { pWnd->EnableWindow(bShow); if(bShow)

{ pWnd->ShowWindow(SW_SHOW); pWnd->CenterWindow();//居中显示 }

else pWnd->ShowWindow(SW_HIDE); }

void CMyDlg::DoTab(int nTab)

{ if(nTab>2) nTab=2;//确定nTab值不能超过范围 if(nTab<0) nTab=0; BOOL bTab[3];

bTab[0]=bTab[1]=bTab[2]=FALSE; bTab[nTab]=TRUE;

//切换对话框的显示和隐藏

SetDlgState(m_pTab1Dlg,bTab[0]); SetDlgState(m_pTab2Dlg,bTab[1]); SetDlgState(m_pTab3Dlg,bTab[2]); }

书(11) int nSelect=m_Tab.GetCurSel(); if(nSelect>=0) DoTab(nSelect); 书(12)…… 书(13)

m_pTab1Dlg=new CTab1Dlg();//为无模式对话框分配空间 m_pTab2Dlg=new CTab2Dlg(); m_pTab3Dlg=new CTab3Dlg(); //创建无模式对话框,指定标签控件为无模式对话框的父窗口 m_pTab1Dlg->Create(IDD_DIALOG1,&m_Tab); m_pTab2Dlg->Create(IDD_DIALOG2,&m_Tab); m_pTab3Dlg->Create(IDD_DIALOG3,&m_Tab); m_ImageList.Create(16,16,ILC_COLOR|ILC_MASK,3,0);//创建图象列表 m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));//从图标加到图象列

//表中

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2)); m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON3)); m_Tab.SetImageList(&m_ImageList);//设置TAB控件所使用的图象列表 m_Tab.InsertItem(0,\"基本信息\ m_Tab.InsertItem(1,\"成绩\ m_Tab.InsertItem(2,\"备注\ m_Tab.SetMinTabWidth(80);//设置标签项的最小宽度 m_Tab.SetPadding(CSize(12,3));//设置标签项和图标周围的间隔 m_Tab.SetCurSel(0); DoTab(0);

书(14)if(m_pTab1Dlg) delete m_pTab1Dlg; if(m_pTab2Dlg) delete m_pTab2Dlg; if(m_pTab3Dlg) delete m_pTab3Dlg;

书(15)CheckRadioButton(IDC_RADIO_MAN_1,IDC_RADIO_WOMAN_1, IDC_RADIO_MAN_1); 书(16)编译运行

9、通用对话框和消息对话框 A)通用对话框

Windows提供了一组标准用户对话框,它们都具有相应的MFC库中的类 来支持。所有通用对话框类都是从一个公共的基类CCommonDialog派生而来 的。见书238页表5.28列出了这些通用对话框。

这些对话框都有一个共同特点:它们都从用户获取信息,但并不对信息进 行处理。例如:文件对话框可以帮助用户选择一个用于打开的文件,但它实际 上只是给程序提供了一个文件路径名,用户的程序必须调用相应的成员函数才 能打开文件。类似地,字体对话框只是填充一个描述字体的逻辑结构,但它并 不创建字体。

*** 例如:制作一个利用CFileDialog(文件对话框)类,弹出“打开”对话框的应用程

在打开一个文本文件或是位图文件时,往往要使用到CFileDialog类,CFileDilog类可以创建一个“打开”对话框,再通过调用其成员函数完成相应的功能,这里举出一些常用的函数。

CFileDialog(BOOL bOpenFileDialog,LPCTSTR lpszDefExt=NULL, LPCTSTR lpszFileName=NULL,DWORD dwFlags=

OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,

LPCTSTR lpszFilter=NULL,CWnd *pParentWnd=NULL); //该函数用于创建CFileDialog类对象,如: CFileDialog dlg;

Virtual int DoModal();//用于显示对话框,如:dlg.DoModal(); CString GetPathName()const;//用于获取文件名和文件路径名 CString GetFileName()const;//用于获取文件名 操作步骤如下:

1)创建一个单文档应用程序,名为:通用对话框 2)创建弹出“打开”对话框的菜单命令

MenuIDR_MAINFRAME双击空白菜单名处写:打开,ID处写:

ID_FILEOPEN

3)将ID_FILEOPEN连到view.cpp中去 4)添加代码:

(1)在view.h的public里加:

CString FilePathname;//用于存储将要打开文件的路径名 CString FileName; //用于存储文件名

(2)完成菜单命令函数的代码: void CMyView::OnFileopen()

{

CFileDialog dlg(TRUE,_T(“TXT”),_T(“*.TXT”),

OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, _T(“文本文件(*.TXT)|*.TXT|”));//设置打开文件为”.TXT” if(IDOK==dlg.DoModal()) {

FilePathname.Format(“%s %s”,”filepath:”,dlg.GetPathName()); FileName.Format(“%s %s”,”filename:”,dlg.GetFileName());

}

Invalidate();

}

(3)在OnDraw()函数中添加如下代码:

-----

pDCTextOut(0,0,FileName);//显示文件名

pDCTextOut(0,20,FilePathname);//显示路径名

5)运行后,点刚建立的菜单,出现对话框,你随便写一个已有的文本文件(*.txt)文件名,

便在屏幕上显示处文件名、路径名。 B)消息对话框

消息对话框是最简单的一类对话框,它只是用于显示信息。在Visual C++6.0 的MFC类库中就提供相应的函数实现这样的功能,使用时,只要在用户程序 任何地方调用它们即可。函数原型如下:

int AfxMessageBox(LPCTSTR lpszText,UINT nType=MB_OK,UINT nIDHelp=0); //是全程函数,可以用在任何地方

int MessageBox(LPCTSTR lpszText,LPCTSTR lpszCaption=NULL,UINT nType= MB_OK); //只能用于控件、对话框、窗口等一些窗口类中。 参数:IDOK表示用户单击[OK]按钮

lpszText表示在消息对话框中显示的字符串文本

lpszCaption表示消息对话框的标题,为NULL时使用默认标题 nIDHelp表示消息的上下文帮助ID号

nType表示消息对话框的图标类型以及所包含的按钮类型,这些类型是

用MFC预先定义的一些标识符来指定的,见书240页表5.29和5.30所示。 例:消息对话框的使用

(1)建一个基于对话框的应用程序

(2)拖入对话框中两个按钮控件:BUTTON1 和BUTTON2 (3)将这两个控件的映射消息分别加到:CMyDlg.cpp中

ViewClassWizard ClassnameCMyDlgIDC_BUTTON1

BN_CLICKEDFunctionEditCode

(4)在函数BUTTON1中加: void CMyDlg::OnButton1()

{ // TODO: Add your control notification handler code here MessageBox(\"你是学物理的吗?\ \"提问\

}

(5)在函数BUTTON2中加: void CMyDlg::OnButton2()

{ // TODO: Add your control notification handler code here AfxMessageBox(\"你是学化学的吗?\ MB_YESNOCANCEL|MB_ICONEXCLAMATION);

}

附加:计算器应用程序

一、建一个基于对话框的应用程序,将对话框上的OK和Cansel删掉 二、可视化设计

Edit Box (一个编辑框) 7 8 9 + C (全是按钮Button)(20个) 4 5 6 - sqrt 1 2 3 * 1/x 0 +/- . / = 对应的各控件的属性:

对象 ID属性 Caption属性 Edit IDC_DISPLAY Edit Button IDC_BUTTON0 0 Button IDC_BUTTON1 1 : : : : : : Button IDC_BUTTON9 9 Button IDC_BUTTON_POINT . : IDC_BUTTON_SIGN +/- : IDC_BUTTON_ADD +

: IDC_BUTTON_MINUS - : IDC_BUTTON_MUTIPLY * : IDC_BUTTON_DIV / : IDC_BUTTON_CLEAR C : IDC_BUTTON_SQRT sqrt : IDC_BUTTON_RECIPROCAL 1/x : IDC_BUTTON_EQUAL = 三、为编辑框IDC_DISPLAY引入变量m_display

为了能够在程序运行过程中,将输入的数据和计算的结果在编辑框上显示,必须为它引入一个变量,从而能够使编辑框以变量的形式出现在程序中,利用函数:UpdateData(true)或UpdateData(false)就可以达到目的。

ViewClassWizardMember VariableClass name:CMyDlgControl Ids:IDC_DISPLAYAdd Variable 写:m_display (Value String) 四、为CMyDlg类添加数据成员

1、为了实现计算功能,需要向CMyDlg类(CMyDlg.h)添加变量

double m_first; //存储一次运算的第一个操作数以及一次运算的结果 double m_second; //存储一次运算的第二个操作数 double m_coff; //存储小数点的系数权值 CString m_operator; //存储运算操作数

注意:如上4个变量的添加方法,也可用右键对准CmyDlg类的方法添加。 2、在构造函数中初始化成员变量 m_first=0.0; m_second=0.0; m_operator=_T(\"+\"); m_coff=1.0;

五、为Button按钮的BN_CLICKED事件添加响应函数即映射消息(在CMyDlg类中) Object IDs Messages Member Functions IDC_BUTTON0 BN_CLICKED OnOnButton0() IDC_BUTTON1 BN_CLICKED OnOnButton1()

: : :

IDC_BUTTON9 BN_CLICKED OnOnButton9() IDC_BUTTON_POINT BN_CLICKED OnButtonPoint() IDC_BUTTON_SIGN : OnButtonSign() IDC_BUTTON_ADD : OnButtonAdd() IDC_BUTTON_MINUS : OnButtonMinus() IDC_BUTTON_MUTIPLY : OnButtonMutiply() IDC_BUTTON_DIV : OnButtonDiv() IDC_BUTTON_CLEAR : OnButtonClear() IDC_BUTTON_SQRT : OnButtonSqrt()

IDC_BUTTON_RECIPROCAL : OnButtonReciprocal() IDC_BUTTON_EQUAL : OnButtonEqual()

ViewClassWizardCmyDlgIDC_BUTTON0BN_CLICKEDAdd FunctionOnButton0OK 按如上步骤将如上所有控件消息全加到CMyDlg类中去。

六、编写程序代码

当鼠标单击对话框中某个Button按钮(比如”8”)时,导致Windows产生BN_CLICKED消息。而要完成 某种功能,就要由消息响应函数中的代码来实现。因此,要编写程序代码,具体步骤如下: 1、为数字”N”按钮的消息响应函数添加代码 算法设计:

(1)作为整数输入数字N时(数字N=0、1、2、、、、、9)

m_second = m_second*10+N;

(2)作为小数输入数字N时(N=0、1、2、、、、9)

m_second = m_second + N*m_coff; m_coff *=0.1;

所以,在数字”8”按钮的消息响应函数中添加如下代码: void CMyDlg::OnButton8() { // TODO: Add your control notification handler code here if(m_coff==1.0)//作为整数输入 m_second=m_second*10+8; else//作为小数输入 { m_second = m_second+8*m_coff; m_coff *= 0.1; } UpdateDisplay(m_second);//更新编辑框的数据显示 }

其它数字按钮的消息响应函数加代码,完全类似。 2、为运算符按钮的消息响应函数添加代码:

当点击四则运算符(+、-、*、/)时,就是要将一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框中显示。由以下算法描述:

(1)m_first与m_second做m_operator运算后m_first (2)0m_second

(3)m_firstm_display(显示)

(4)用当前点击的运算符m_operator (5)将小数的权值变量m_coff置1.0复位

点击” + “运算符,在消息响应函数中编写如下代码: void CMyDlg::OnButtonAdd() { // TODO: Add your control notification handler code here Calculate(); m_operator=\"+\"; }

其他,” - “ “ * “ “ / ” 完全类似。

3、为等号 “ = “按钮消息响应函数添加代码: 当点击等号 “ = “ 按钮时,算法设计如下:

(1)m_first与m_second作m_operator运算后m_first (2)m_firstm_display(显示) (3)0m_second

(4)0first

(5)将小数的权值m_coff置1.0 (6)输入的运算符m_operator void CMyDlg::OnButtonEqual() { // TODO: Add your control notification handler code here Calculate(); m_first=0.0; m_operator=\"+\"; }

4、在OnButtonSqrt()函数中,编写如下代码: void CMyDlg::OnButtonSqrt() { // TODO: Add your control notification handler code here m_second=sqrt(m_second); UpdateDisplay(m_second); }

5、为 “ +/- “ “ . “ “ C “ 和 “ 1/x “ 按钮的消息响应函数编写代码: // “ C “

void CMyDlg::OnButtonClear() { // TODO: Add your control notification handler code here m_first=0.0; m_second=0.0; m_operator=\"+\"; m_coff=1.0; UpdateDisplay(0.0); }

// “ 1/x “

void CMyDlg::OnButtonReciprocal() { // TODO: Add your control notification handler code here if(fabs(m_second)<=0.000001) { m_display=\"除数不能为零\"; UpdateData(false); return; } m_second=1.0/m_second; UpdateDisplay(m_second); } // “ . “

void CMyDlg::OnButtonPoint() {

// TODO: Add your control notification handler code here m_coff=0.1; }

// “ +/- “

void CMyDlg::OnButtonSign() { // TODO: Add your control notification handler code here m_second=-m_second; UpdateDisplay(m_second); }

6、还要添加四则运算函数和显示函数

在工作区窗口,单击ClassView标签,之后选CMyDlg类,右键单击,在弹出的快捷菜单中选择 ”Add Member Function….” 写:void Calculate(void) 之后重复上面步骤再加入,

写:void UpdateDisplay(double lVal) 这两个函数的代码如下:

void CMyDlg::Calculate() {

switch(m_operator.GetAt(0)) {

case '+': m_first +=m_second; break; case '-': m_first -=m_second; break; case '*': m_first *=m_second; break; case '/': if(fabs(m_second)<=0.000001) { m_display=\"除数不能为零\"; UpdateData(false); return; } m_first /=m_second; break; }

m_second=0.0; m_coff=1.0;

UpdateDisplay(m_first);//更新编辑框的显示内容 }

void CMyDlg::UpdateDisplay(double lVal) {

m_display.Format(_T(\"%f\"),lVal);

int i=m_display.GetLength();//格式化输出,

//将输出结果后的零全部截去 while(m_display.GetAt(i-1)=='0') {

m_display.Delete(i-1,1); i--; }

UpdateData(false); }

7、在CMyDlg.cpp文件的头部加:#include “math.h” 8、编译运行正确后,便可随意进行四则运算等 说明:

1、关于UpdateData()函数

UpdateData()函数是CDialog的基类CWnd的成员函数,其函数原型如下:

BOOL UpdateData(BOOL bSaveAndValidate = TRUE);

一般在对话框的派生类中,利用UpdateData()函数进行控件和相应变量之间的数据传递,形式如下:

UpdateData(TRUE); //将控件中的数据传递给相应的变量

UpdateData(FALSE); //将变量中的数据传递给相应的控件,即显示

例如:在UpdateDisplay()函数中,首先将函数参数lVal通过转化和截去零操作,赋值给与编辑框控件相关联的变量m_display,最后调用UpdateData(false)使变量m_display的值显示编辑框中。 2、数据交换和校验

对话框数据交换(dialog data exchange,简称DDX)可以方便地实现对话框中控件数值的初始化和获取用户的数据输入。对话框数据校验(Dialog data validation,简称DDV)可以对对话框中的控件的数据进行校验。具体实现时可以通过ClassWizard定义与控件关联的数据成员实现DDX,通过限定数据范围实现DDV,例如:

在对话框“IDD_MY_DIALOG”中,通过ClassWizard对标识号为“IDC_DISPLAY”的“Edit Box”控件创建了m_display变量,数据类型为CString 。ClassWizard自动地在文件MyDlg.cpp中创建了相应的对话框数据交换代码: void CMyDlg::DoDataExchange(CDataExchange* pDX)//自动生成的对 //话框数据交换代码 { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CMyDlg) DDX_Text(pDX, IDC_DISPLAY, m_display); //}}AFX_DATA_MAP }

3、字符串CString类

CString类的对象由一个长度可变的字符序列组成,包含很多成员函数用来操作字符串,可以很方便地实现对字符串的各种操作。CString类中的字符是TCHAR类型的 (1)构造函数

CString(); //产生一个空的CString对象

CString(const CString&stringSrc); //用另一个CString对象的值初始化对象 CString(TCHAR ch,int nRepeat=1); //用一个字符重复若干次初始化对象

CString(LPCTSTR lpch,int nLength); //用一个字符数组的指定长度初始化对象 CString(const unsigned char *psz); //从一个无符号字符指针初始化对象 CString(LPCWSTR lpsz); //从一个Unicode字符串初始化对象 CString(LPCSTR lpsz); //从一个ANSI字符串初始化对象 (2)常用成员函数

CString类的常用成员函数:

int GetLength()const //获取CString类对象包含的字符串的长度

BOOL IsEmpty()const //测试CString类对象包含的字符串是否为空 void Empty() //使CString类对象包含的字符串为空字符串 TCHAR GetAt(int nIndex)cont //获取字符串指定位置处的字符 void SetAt(int nIndex,TCHAR ch) //设定字符串指定位置处的字符 TCHAR operator[](int Index)const //获取字符串指定位置处的字符

Operator LPCTSTR()CONST //返回指向存储在CString类对象内的字符串指针 int Compare(LPCTSTR lpsz)const //比较两个字符串,类似于C中strcmp()函数

int CompareNoCase(LPCTSTR lpsz)const //类似于C中Compare()函数,但忽略字符大小写 MakeUpper //将字符串中所有的字符全部转化成大写形式 MakeLower //将字符串中所有的字符全部转化成小写形式 例1:连接字符串

CString m_str1=”下午”; CString m_str2=”好!”;

CString m_str3=m_str1+m_str2; 结果m_str3的值为“下午好!” 例2:比较字符串 CString m_str1=”a”; CString m_str2=”b”;

int result=m_str1.Compare(m_str2);

if(result==0) AfxMessageBox(“两者相同”); else

if(result>0) AfxMessageBox(“m_str1大于m_str2”); else

AfxMessageBox(“m_str1小于m_str2”);

附加:向导对话框

本节内容书上没作介绍,考虑实际中要经常用到“向导对话框”,所以我们作为插入内容给同学们介绍,望大家能很好地掌握。 1、向导对话框是什麽式样?

(1) 我们经常在应用软件上如:财务软件、信息管理软件和网上看到:一页一页向前

(Next),或返回一页(Back)或 结束(Finish)的界面,这是完成可视化项目界面必须的,因为信息太多,无法用一个页面完成显示,所以必须象看书一样,一页一页向前翻,如:人才招聘网上的全国各单位招聘人才情况,就有好多好多页等等。 (2)见实例《南山商城商品展销》程序的实际应用情况。 2、向导对话框制作的指导思想

(1)向导对话框实质上是一种特殊的属性表,和属性表不同的是它使用按钮来完成从一页到另一页的移动,而不是选项卡。由于它也属于属性表,只不过是一种特殊的,所以与其对应的MFC类也是属性表类:CpropertySheet(用于表示属性单,也称一组标签对话框)和属性页类:CpropertyPage(用于表示属性单中的单个页面,页面也称表页对话框),在向导对话框程序中,属性表的创建方法没有改变,只是在调用DoModel()函数(显示模式属性单)之前应先调用SetWizardMode()函数(使wizard模式有效),将属性表的操作方式设置为向导模式。

(2)举例:创建属性表,看属性表是如何形式,并能区别于向导对话框。

属性表是一个带选项卡的对话框,它包含2页或2页以上的对话框(能把多个对

话框集中起来),用户可以通过单击对话框顶端的标签来翻动页。

3、制作说明及本节所作出的向导对话框的样式

a、 在向导模式下,每一个属性页都有Back,Next,Finish按钮,MFC自动地调用

OnSetActive()(当前页成为活动页时,由框架调用)函数,因此我们可以重载OnSetActive()函数,在此函数中利用SetWizardButton(wizard按钮有效)设置希望出现的按钮,在向导程序的最后一页,可以通过SetFinishText(设置Finish按钮的文本)设置Finish按钮所显示的文字。 b、举出本节所作出的向导对话框的样式 4、向导对话框的制作步骤:

(1)创建一个基于对话框的应用程序框架,工程名为:向导对话框 。 (2)创建3个对话框(向前翻3页)

a、InsertResource展开Dialog点重其中IDD_PROPPAGE_MEDIUMNew

将创建好的这个对话框的ID标识符该成IDD_STEP1,并在language处选

Chinese[P.R.C] 。

b、按a的步骤再建2个同样的对话框: IDD_STEP2, IDD_STEP3 (3)分别为这3个对话框建类

a、双击第一个对话框摸板,在弹出的Adding a Class对话框中选Create a new Class 后单击OK,在弹出的New Class对话框中的类名处写:CStep1,基类选

CpropertyPage(用于表示属性单中的单个页面,页面也称表页对话框)OK。 b、按a的步骤分别为第2个和第3个对话框建类,类名分别为:CStep2,CStep3, 基类也都是CpropertyPage。

(4)向这三个对话框各加一个按钮,分别写:第一个对话框、第二个对话框、 第三个对话框,用以区分这三个对话框。

(5)利用ClassWizard为第一个对话框类CStep1增加消息处理函数OnSetActive,在此函数中激活Next按钮,其步骤如下:

ViewClassWizard在Class name处选CStep1在Object IDs处选中CStep1在

Messages处选中OnSetActive点Add Function将此函数加到CStep1类中Edit Code进入此函数处。

(6)向CStep1类中的OnSetActive函数填代码: BOOL CStep1::OnSetActive() {

CPropertySheet *pSheet = (CPropertySheet *)GetParent(); //构造属性单的指针 ASSERT_KINDOF(CPropertySheet,pSheet);//测试获取的指针 pSheet->SetWizardButtons(PSWIZB_NEXT); }

(7)仿照(5)的步骤,利用ClassWizard为第二个对话框类CStep2增加消息处理函数OnSetActive,在此函数中激活Next按钮及Back按钮。(将(5)步中的CStep1都改成CStep2)。 (8)向CStep2类中的OnSetActive函数填代码:

BOOL CStep2::OnSetActive() {

CPropertySheet *pSheet = (CPropertySheet *)GetParent(); //构造属性单的指针 ASSERT_KINDOF(CPropertySheet,pSheet);//测试获取的指针 pSheet->SetWizardButtons(PSWIZB_NEXT| PSWIZB_BACK); }

(9)仿照(5)的步骤,利用ClassWizard为第三个对话框类CStep3增加消息处理函数

OnSetActive,在此函数中激活Finish按钮及Back按钮。(将(5)步中的CStep1都改成CStep3)。

(10)向CStep3类中的OnSetActive函数填代码: BOOL CStep3::OnSetActive() {

CPropertySheet *pSheet = (CPropertySheet *)GetParent(); //构造属性单的指针 ASSERT_KINDOF(CPropertySheet,pSheet);//测试获取的指针 pSheet->SetWizardButtons(PSWIZB_FINISH| PSWIZB_BACK);

}

(11)创建一个属性表类CWizardSheet来显示已创建的属性页:

ViewClassWizardAdd ClassNew类名写:CWizardSheet基类选CPropertySheet

(12)打开CWizardSheet类的头文件加入: #include “Step1.h”

#include “Step2.h”

#include “Step3.h”

(13)通过ClassView标签在CWizardSheet类中填加Step1、Step2、Step3三个类的成员变量即:

ClassView鼠标右键对准CWizardSheet类Add Member Variable--在弹出的对话

框Add Member Variable的变量类型Variable Type处写:CStep1在变量名Variable Name处写:m_step1并在Access处置缺省public即可。

重复上面步骤,再为CStep2、CStep3类分别加m_step2、m_step3成员变量。 (14)在WizardSheet.cpp的2个构造函数中,都加入下列代码:

AddPage(&m_step1);//增加一页到属性单中,引用&m_step1是增加到属性单中的//页 AddPage(&m_step2); AddPage(&m_step3);

(15)修改“向导对话框”项目中的应用程序类(向导对话框.cpp)的InitInstance()函数,删除以下代码:

CMyDlg dlg; //定义本项目的对象

m_pMainWnd = &dlg;//将本项目类的地址 m_pMainWnd使m_pMainWnd指向//该类 int nResponse = dlg.DoModal();获得的对话框 nResponse if (nResponse == IDOK)//判别nResponse若等于IDOK // 以上是显示单一对话框的过程 (16)在上面的删除处,填加下列代码:

CWizardSheet dlg(“wizard sheet”); // 我们自己加的属性单类(也称一组标签对话//框)的对象\"wizard sheet\"属性单中的标题字符串, 可以为空,但必须要有\" \"。 m_pMainWnd=&dlg; //使wizard模式有效 dlg.SetWizardMode();//显示模式属性单 int nResponse=dlg. DoModal();

if(nResponse==ID_WIZFINISH)//如果我们按了结束按钮的话,就作结束处理 (以下接原有的代码)

(17)在“向导对话框.cpp”中,加入: #include \"WizardSheet.h\" (18)编译运行

第五章结束

因篇幅问题不能全部显示,请点此查看更多更全内容