《VC++6.0-MFC编程实例》由会员分享,可在线阅读,更多相关《VC++6.0-MFC编程实例(139页珍藏版)》请在金锄头文库上搜索。
1、第10章VisualC+编程实例第第10章章 Visual C+编程实例编程实例10.1 MFC编程流程编程流程10.2 常用常用FC类和消息处理类和消息处理10.3 对话框的应用对话框的应用10.4 菜菜 单单 的的 应应 用用10.5 工具栏应用工具栏应用第10章VisualC+编程实例10.1 MFC编程流程编程流程 在普通的C/C+程序中,可以看到程序从main函数开始到结束的所有代码,但在VisualC+中MFC封装了一部分类,同时也隐藏了一部分代码,因此我们看不到源程序的所有代码,例如从项目的所有源文件中找不到main函数。基本对话框的MFC程序流程图如图10-1所示。第10章Vi
2、sualC+编程实例图10-1第10章VisualC+编程实例一个MFC程序运行的一般过程如下:(1)生成CwinApp的一个实例(调用CwinApp的构造函数),初始化全局对象;(2)Win32入口程序函数WinMain调用函数AfxWinMain;(3)AfxWinMain调用函数CwinApp的成员函数InitInstance;(4)AfxWinMain调用函数CwinApp的成员函数Run;(5)AfxWinMain函数返回到WinMain,WimMain结束,程序结束。第10章VisualC+编程实例例10-1吹泡泡程序。每当用户在窗口客户区中按下鼠标左键时即可产生一个泡泡(彩色圆形
3、)。设计思路:显示一个泡泡所需的数据包括其位置和大小,在MFC中可用其包含矩形表示。可设置一数组,每当用户按下鼠标左键时,就产生一个泡泡的数据并存入数组中。最后,由框架窗口类的OnPaint()函数显示所有的泡泡。第10章VisualC+编程实例#include#defineMAX_BUBBLE250classCMyWnd:publicCFrameWndCRectm_rectBubbleMAX_BUBBLE;intm_nBubbleCount;public:CMyWnd()m_nBubbleCount=0;第10章VisualC+编程实例protected:afx_msg void OnLBu
4、ttonDown(UINT nFlags,CPoint point);afx_msgvoidOnPaint();DECLARE_MESSAGE_MAP();/消息映射BEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd)ON_WM_LBUTTONDOWN()ON_WM_PAINT()END_MESSAGE_MAP()第10章VisualC+编程实例/框架窗口类的成员函数void CMyWnd:OnLButtonDown(UINT nFlags,CPoint point)if(m_nBubbleCountMAX_BUBBLE)intr=rand()%50+10;CRectrect
5、(point.x-r,point.y-r,point.x+r,point.y+r);m_rectBubblem_nBubbleCount=rect;m_nBubbleCount+;InvalidateRect(rect,FALSE);第10章VisualC+编程实例voidCMyWnd:OnPaint()CPaintDCdc(this);CBrushbrushNew;CPenpenNew;brushNew.CreateSolidBrush(RGB(rand()%255,rand()%255,rand()%255);penNew.CreatePen(PS_SOLID,1,RGB(255,0,0)
6、;dc.SelectObject(&brushNew);dc.SelectObject(&penNew);第10章VisualC+编程实例for(inti=0;iCreate(0,_T(吹彩色泡泡);pFrame-ShowWindow(m_nCmdShow);this-m_pMainWnd=pFrame;returnTRUE;CMyAppThisApp;/全局应用程序对象按【Ctrl+F5】运行程序,运行结果如图10-2所示。第10章VisualC+编程实例说明:该程序声明了两个类,一个是由应用程序类CwinApp派生出来的CmyApp类,一个是由框架窗口CframeWnd类派生出来的CmyW
7、nd类。MFC的基本类名均以字母C打头,习惯上在为使用MFC编写的应用程序中的类起名时也这样做。在程序中还声明了一个CmyWnd类的全局对象ThisApp。第10章VisualC+编程实例图10-2第10章VisualC+编程实例在CmyWnd类中声明了一个数组成员m_rectBubble,用于存放泡泡的数据;另外,还声明了一个整型数据成员m_nBubbleCount,用来存放数组中泡泡的实际数量。在框架窗口类的构造函数中该成员变量被初始化为0,由于构造函数非常简单,因此使用了内联函数的形式。第10章VisualC+编程实例OnPaint()函数用于绘制客户区的内容。要完成这项任各,需要先建立
8、一个设备环境(DeviceContext),这可以通过声明一个CpaintDC类的对象dc实现。在声明语句中,应将当前窗口对象指针this传给CpaintDC类的构造函数,把绘图区域确定为当前窗口的客户区。Windows在窗口更新、移动、改变尺寸或移去覆盖在其上的其它窗口对象时均会向该窗口发送WM_PAINT消息,从而触发应用程序调用OnPaint()函数重绘窗口客户区。第10章VisualC+编程实例OnPaint()函数根据数组m_rectBubble的内容画出一个泡泡。其中语句。dc.SelectStockObject(LTGRAY_BRUSH);用于选择一个库存画刷,画刷决定了所画图形
9、(如椭圆、矩形和多边形等)内部的颜色。在处理鼠标消息的ONLButtonDown()函数中,语句intr=rand()%50+10;随机确定了要画出的泡泡的半径(范围为1050像素点),其中全局函数rand()可产生一个随机整数。第10章VisualC+编程实例调试:首先,使用VisualC+集成开发环境中的菜单选项“文 件 /新 建 ”, 并 在 项 目 选 项 卡 中 选 择 “Win32Application。其次,在编译时要确定应用程序的可执行程序如何使用MFC的类库。一种方法是使用共享的动态链接库(DLL)。这种链接方式显著地减小了应用程序的可执行文件的大小,并能有效地利用系统资源。
10、第10章VisualC+编程实例用系统资源。然而,动态链接到MFC时要求提供Mfcnn.dll库文件,文件名中的nn代表MFC的版本号。该文件通常在WindowsSystem或System32文件夹下。如果一个应用程序动态链接到了MFC,但该应用程序通常用在那些可能没有Mfcnn.dll库的计算机系统上,则应把这个库文件作为应用程序包的一部分提供给用户。Microsoft允许程序员自由地把这些库文件附在应用程序中。第10章VisualC+编程实例另外,也可以选择应用程序静态链接到MFC。静态链接意味着,应用程序不依赖于MFC库文件的存在(但仍然可能需要Msvcrt.dll文件)。静态链接的代价
11、是可执行文件更大,而且MFC内存的利用可能不够充分。在菜单中选择“工程”中的“设置”对话框,在对话框右方的“General”选项卡中通过组合框“MicrosoftFoundationClasses”选择使用MFC类库的方法。可选项有三种,分别为“NotUsingMFC(不使用MFC),UseMFCinaSharedDLL(以动态链接库方式使用MFC)”和“UseMFCinaStaticLibrary(以静态库方式使用MFC)”。第10章VisualC+编程实例10.2 常用常用FC类和消息处理类和消息处理10.2.1常用MFC类MFC的类构成了一个完整的体系,该体系由一个被称为Cobject的
12、类作为基类,其它类大部分由该类派生而来,如CWnd(窗口类)、Cdocument(文档类)、Cfile(文件类)等。也有一部分类如字符串类,Cstring和时间类Ctime等则不从Cobject继承。第10章VisualC+编程实例1.窗口公共基类CWnd类CWnd对所有Windows窗口提供功能支持,它是所有窗口类的直接或间接父类。一个CWnd对象和一个Windows窗口是有本质区别的,尽管它们有密切的联系。CWnd对象是一个概念,即类的实例,而Windows窗口则是指向Windows内部数据结构的一个句柄,它的创建和显示要消耗系统资源。一个CWnd对象通过其构造函数被创建,被析构函数销毁,
13、而一个Windows窗口则通过CWnd的Create函数创建,被DestroyWindow函数销毁。第10章VisualC+编程实例1)窗口句柄(1)窗口句柄的创建:当CWnd:Create被调用时,Windows窗口被创建,窗口句柄存放在CWnd的成员变量m_hWnd中。(2)程序中窗口句柄的取得:可以直接利用成员变量m_hWnd,但安全的方法是调用函数CWnd:Get(),它返回与窗口对象相关联的句柄,并且当窗口对象没有关联句柄时或当前CWnd指针为NULL时返回空指针。(3)窗口句柄的销毁:调用CWnd:DestroyWindow。第10章VisualC+编程实例2)窗口的大小和位置(1
14、)IsIconic:窗口是否处在最小化状态。(2)IsZoomed:判断窗口是否在最大化状态。(3)MoveWindow:改变窗口的大小、位置和Z轴顺序。Z轴顺序指本窗口和其他窗口的覆盖关系。第10章VisualC+编程实例3)窗口的状态(1)ShowWindow:显示或隐藏一个窗口,显示可以有多种方式:最大化、最小化、正常显示等。(2)IsWindowEnabled:判断一个窗口是否可见。(3)IsWindowEnabled:判断窗口的禁止/使能状态,禁止状态的窗口不能响应用户的键盘和鼠标的输入。(4)EnableWindow:设置窗口的禁止/使能状态,参数为true表示使能。第10章Vis
15、ualC+编程实例4)定时器函数(1)SetTimer:开始一个系统定时器。定时器的作用是每隔指定时间发一次WM_TIMER消息。(2)KillTimer:结束一个指定的系统定时器。5)提示函数(1)FlashWindow:闪烁窗口。(2)MessageBox:弹出一个标准消息框。第10章VisualC+编程实例例如 : 开 始一个系 统定 时器每 0.5秒 发一次WM_TIMER消息,代码为:SetTimer(1,500,NULL):其中,第一个参数表示定时器的标识,第二个参数表示发送WM_TIMER的间隔时间,第三个参数是一个回调函数,一般设为NULL。可以在WM_TIMER消息的处理函数
16、OnTimer(通过ClassWizard添加)中加入处理代码来响应定时器消息。结束定时器的方法是调用以定时器标识为参数的函数KillTimer,比如:KillTimer(1);第10章VisualC+编程实例2字符串类CStringCstring类是MFC对字符串的封装,它包含一个可变长的字符序列,提供了很多串操作,使用它比使用其它字符串类型更加方便。可以说,几乎每个MFC程序都要用到这个类。CString没有继承任何类,且其各个字符都是TCHAR类型。CString对象可以随着串合并操作动态增加其长度,而无须用户来对其长度进行专门设置。CString可以看作一个串类型,而不是一个指向字符串
17、的指针。第10章VisualC+编程实例1)CString的构造函数CString类拥有众多的构造函数,用于以不同的数据类型和不同的方式构造一个字符串对象,它们是(1)CString();/无参数的构造函数,产生一个空的Cstring对象(2)CString(constCstring&stringSrc);/用另外一个Cstring对象的值初始化对象(3)CString(TCHARch,intnRepeat=1);/用一个字符重复若干次来初始化对象第10章VisualC+编程实例(4)CString(LPCTSTRlpch,intnLength);/用一个字符数组和一定长度初始化对象(5)CS
18、tring(constunsignedchar*psz);/从一个无符号字符指针构造对象例如:CStrings1;CStrings2(big);CStrings3=s2;CStrings4(s2+s3);第10章VisualC+编程实例2)CString的基本操作Cstring的基本操作如下:(1)求得到字符串长度:GetLength返回一个int类型的数。(2)判断字符串是否为空:BOOLIsEmpth()const。(3)强制字符串长度为0:voidEmpty()。(4)得到字符串某位置的字符:TCHARGetAt(intnIndex)const。(5)设置字符串某位置的字符:voidSe
19、tAt(intnIndex,TCHARch)。(6)强制转换为字符串指针类型:operatorLPCTSTR。第10章VisualC+编程实例例如,获取字符串str最后一个字符的语句如下:CStringstr=aabbcde;Charc1=str.GetAt(str.GetLength()-1);第10章VisualC+编程实例3)串提取串提取函数由于根据某种原则从串中提取一个子串。相关函数包括Mid,Left和Right。(1)CStringMid(intnFirst)const;/获取从nFirst位置字符开始的子串(2)CStringMid(intnFrist,intnCount)con
20、st;/获取从nFirst位置的字符开始包含nCount/个字符的子串(即到nFirst+nCount-1位置/的字符为止)第10章VisualC+编程实例(3)CStringLeft(intnCount)const;/获取左边nCount个字符所构成的子串(4)CStringRight(intnCount)const;/获取右边nCount个字符所构成的子串4)转换字符串(1)voidMakeUpper();/将字符串中所有字符换成大写(2)voidMakeLower();/将字符串中所有字符换成小写(3)voidMakeReverse();/将字符串中各字符的顺序倒转(4)voidEmpt
21、y();/将字符串中所有字符删除第10章VisualC+编程实例5)字符串格式化函数字符串格式化函数是CString:Format,它根据一个参数字符串(格式控制字符串)和几个变量来格式化一个串。该函数的格式如下:voidFormat(LPCTSTRlpszFormat,.);voidFormat(UINTnFormatID,.);第10章VisualC+编程实例该成员函数用于根据格式lpszFormat,用其它数据构造一个字符串。其中省略号“.是输出参数表,每个参数可以是一个变量或表达式。函数Format常常用于把其它类型的变量转换为字符串形式,或者把几个不同类型的值合并成一个字符串的形式。
22、第10章VisualC+编程实例例如:CStrings1,s2,s3;s1.Format(%c,65);s2.Format(float:%f,int:%d,hexint:%x,3.48,20,0xFF);s3.Format(string:%s,formatedfloat:%2.1f,hehe,3.14159);执行以上代码后s1字符串是A,s2字符串是float:3.480000,int:20,hexint:ff,s3字符串是string:hehe,formatedfloat:3.1。第10章VisualC+编程实例3CPoint、Crect和Csize类1)Cpoint类MFC中的Cpoin
23、t类是对Windows结构POINT的封装,凡是能用POINT结构的地方都可以用Cpoint代替。Cpoint提供了一些成员函数,使得操作POINT结构和Cpoint类更加方便。结构POINT表示一个屏幕上的二维点,它的定义如下:第10章VisualC+编程实例typedefstructtagPOINTLONGx;LONGy;POINT;其中x和y分别是点的横坐标和纵坐标。第10章VisualC+编程实例2)CSize类MFC中的Csize类是对indows结构SIZE的封装,凡是能用SIZE结构的地方都可以用CSize代替。结构SIZE表示一个矩形的长度和宽度,它的定义如下:typedefs
24、tructtagSIZEintcx;intcy;SIZE;其中cx和cy分别是矩形的长度和宽度。第10章VisualC+编程实例3)CRect类Crect类是对Windows结构RECT的封装。结构RECT表示一个矩形。TypedefstructtagRECTLONGleft;LONGtop;LONGright;LONGbottom;RECT;其中,left和top分别表示矩形左上角顶点的横、纵坐标;right和bottom分别表示矩形右下角顶点的横、纵坐标。第10章VisualC+编程实例4CPaintDC类在CpaintDC类中封装了大量的绘图和文字输出方法(成员函数)(1)文字信息显示。
25、文字信息显示的成员函数为:BOOLTextOut(intx,inty,LPCTSTRlpszString);该 函 数 用 于 在 指 定 坐 标 (x,y)处 显 示 字 符 串lpszString的内容,显示成功返回非0值,否则返回0。坐标原点(0,0)在客户区左上角,Y轴向下。第10章VisualC+编程实例(2)画点。画点的成员函数为COLORREFSetPixel(intx,inty,COLORREFcolor);COLORREFSetPIxel(POINTpoint,COLORREFcolor);该函数在指定坐标处按给定颜色画点,返回值为原来此坐标处的颜色。(3)取指定坐标点的颜色
26、。取指定坐标点的颜色的函数为:COLORREFGetPixel(intx,inty)const;COLORREFGetPixel(POINTpoint)const;该函数的返回值为指定坐标处的颜色。第10章VisualC+编程实例(4)画线。画线分两步完成:首先确定线的起始位置,然后再调用画线函数。用MovoTo将绘图位置移动到指定位置的原型为:CPointMoveTo(intx,inty);CpointMoveto(POINTpoint);用LineTo函数画线的原型为:BOOLLineTo(intx,inty);BOOLLineTo(POINTpoint);第10章VisualC+编程实例
27、(5)绘制矩形。绘制矩形的成员函数为:BOOLRectangle(intx1,inty1,intx2,inty2);BOOLRectangle(LPCRECTlpRect);该函数的参数为需要绘制的矩形的左上角坐标(x1,y1)和右下角坐标(x2,y2)。(6)绘制椭圆。绘制椭圆的成员函数的原型为:BOOLEllipse(intx1,inty1,intx2,inty2);BOOLEllipse(LPCRECTlpRect);该函数的参数的含义为所绘椭圆的包含矩形的左上角和右下角坐标。第10章VisualC+编程实例10.2.2绘制图形1.图形对象的使用方法普通绘图对象使用的模式为以下4步:(1
28、)生成绘图对象。例如:Cpenpen,*op;pen.CreatePen(PS_SOLID,1,RGB(0,0,0);第10章VisualC+编程实例这里定义的Cpen类指针op用于存储绘图前的画笔,使绘图结束后能够恢复系统原有状态。上面代码中的RGB(0,0,0)是一个宏,用于定义COLORREF类型的颜色。COLORREF实际上是一个32位整数类型,用于表示颜色,其第0、1、2字节分别用于存放该颜色的红、绿、蓝色分量。如果已知某颜色的3个分量,则可使用宏RGB()构造出该颜色:COLORREFRGB(BYTEbRed,BYTEbGreen,BYTEbBlue);第10章VisualC+编程
29、实例其中,第1个参数是颜色的红色分量,第2个参数是颜色的绿色分量,第3个参数是颜色的蓝色分量,各个分量的取值范围为0255。例如:RGB(0,0,0)为黑色,RGB(255,255,255)为白色。第10章VisualC+编程实例(2)将绘图对象选入绘图设备环境。其代码为:op=pDC-SelectObject(&pen);可以看出,将绘图对象选入绘图设备环境的方法是调用CDC:SelectObject()函数,与此同时,还要保留旧的画笔。(3)进行绘图。其代码为:pDC-Moveto(100,100);pDC-Lineto(200,200);第10章VisualC+编程实例(4)绘图工作结束
30、后,进行绘图设备环境的恢复工作。其代码为:pDC-SelectObject(op);如果还要改变pen的参数的话,必须将pen删除:pen.DeletObject();第10章VisualC+编程实例2.画笔和画刷画笔是用来画线的工具,是Cpen类的对象。画刷是用来填充图形的工具,是Cbrush类的对象。1)画笔画笔由Cpen类管理,使用Cpen类对象时,需要无对其进行初始化工作,初始化Cpen类对象的方法有以下3种:(1)调用Cpen类的构造函数。第10章VisualC+编程实例(2)调用Cpen:CreatePen(intnPenStyle,intnWidth,COLORREFcrColo
31、r)函数。其中第1个参数是画笔的样式,可取值为:PS_SOLID/创建实线笔PS_DASH/创建由短线构成的虚线PS_DOT/创建由点构成的虚线PS_DASHDOT/创建由短线和点构成的虚线第10章VisualC+编程实例(3)调用Cpen:CreatePenIndirect()函数,通过LPLOGPEN结构来设置Cpen的属性。例如:CpenpenRed;/说明画笔对象penRed.CreatePen(PS_SOLID,3,RGB(255,0,0);/创建宽度为3的红色实线画笔/使用新的画笔时,要保存原来的画笔以便恢复Cpen*pOldPen;POldPen=dc.SelectObject(
32、&penRed);/以下是作图代码,且使用新画笔画线dc.SelectObject(pOldPen);/恢复原来的画笔第10章VisualC+编程实例2)画刷画刷是用来填充图形的工具,创建画刷有两种方法:一种是调用构造函数,另一种是调用相关的成员函数。使用画刷叶要定义画刷对象,创建画刷并保存原来的画刷,在绘图工作结束后还要恢复原来的画刷。例如:CbrushNewBrush;/声明画刷对象Cbrush*POldBrush;/保存原画刷的指针NewBrush.CreateSolidBrush(PS_SOLID,21,RGB(0,0,255);/建立画刷第10章VisualC+编程实例Pold_Br
33、ush=pDC-SelectObject(&NewBrush);/将画刷选入设备文本对象/使用画刷/恢复原先的画刷对象pDC-Selectobject(PoldBrush);第10章VisualC+编程实例10.2.3消息处理Windows操作系统是一个基于消息的操作系统,其程序总要同消息打交道,这正是Windows程序同DOS程序不同的地方。实际上,Windows系统通过Windows消息告诉所有应用程序发生了什么事件,例如用户点击了鼠标、用户点击了键盘的哪个键等,每个应用程序都有消息处理或一组消息响应函数,用于对消息进行响应。第10章VisualC+编程实例Windows操作系统中定义了9
34、00余个Windows消息,系统将用户的输入传给应用程序,然后又为每个输入产生消息。此外,系统还为应用程序的变化产生消息,如窗口的尺寸发生了变化等。应用程序自已也可能产生消息,用于对应用程序内部发生的特殊事件进行处理或其它应用程序之间的通信。第10章VisualC+编程实例系统向应用程序发送消息时,将向应用程序发送个参数:(1)一个窗口的句柄:窗口句柄用于标识窗口的一个常数,Windows的每个窗口都有一个窗口句柄。消息参数中的窗口句柄标识的是接受消息的窗口。(2)一个消息标识:标识了产生的消息。消息标识的例子有WM_CREATE,其中,WM_代表indowsMessage,是indows窗口
35、产生的消息,而WM_CREATE代表窗口正在被创建,WM_PAINT则代表窗口的客户区需要被重画。第10章VisualC+编程实例(3)两个32位的参数:消息参数定义了Windows应用程序处理消息所需的数据或数据所在的位置,这两个参数的含义与具体的消息有关。消息参数可以包含一个整数、一组标志或一个结构对象的指针。消息参数也可以是NULL,表示消息没有参数。1.Windows消息分类Windows消息大体上可以分为两大类:一类是系统定义的消息,另一类是用户自定义的消息。其中Windows系统定义的消息可以分为以下种:第10章VisualC+编程实例(1)Windows消息:这类消息主要是以WM
36、_作前缀的消息(WM_COMMAND除外,WM_COMMAND消息专门被用于处理菜单和控件发出的消息),且必须由CWnd类或CWnd类的派生类进行处理。消息响应函数也必须被定义在发送消息CWnd类或CWnd派生类中。可见,这类消息属于面向Windows窗口的消息。第10章VisualC+编程实例(2)控件通知消息:这类消息主要由控件或其它子窗口发出,并对各控件或子窗口的父窗口进行处理。这 类 消 息 属 于 WM_COMMAND消 息 , 只 不 过 在WM_COMMAND消息的两个消息参数中包含了每个控件的句柄、标识(ID)和通知消息等信息。(3)Windows命令消息:这类消息是指由菜单、
37、工具条和加速键等发出的WM_COMMAND通知消息。第10章VisualC+编程实例2.鼠标消息处理移动鼠标或点击鼠标按键,Windows便产生一个或多个消息并将其发送给位于鼠标光标下的窗口。编程时常用的鼠标消息有:WM_LBUTTONDOWN/按下鼠标左键WM_LBUTTONUP/释放鼠标左键WM_LBUTTONDBLCLK /双击鼠标左键WM_RBUTTONDOWM /按下鼠标右键WM_RBUTTONUP/释放鼠标右键WM_RBUTTONDBLCLK /双击鼠标右键WM_MOUSEMOVE/移动鼠标第10章VisualC+编程实例对应的Wnd类的消息处理成员函数分别为:voidOnLBut
38、tonDown(UINTnFlags,CPointpoint);voidOnLButtonUp(UINTnFlags,CPontpoint);voidOnLButtonDblClk(UINTnFlags,Cpointpoint);voidOnRButtonDown(UINTnFlags,Cpointpoint);voidOnRButtonUp(UINTnFlags,Cpointpoint);voidOnRButtonDblClk(UINTnFlags,Cpointpoint);voidOnMouseMove(UINTnFlags,Cpointpoint);第10章VisualC+编程实例其中,
39、参数point表示鼠标的位置,nFlags是几个控制键的状态,可以是下列值及其组合:MK_CONTROL/Ctrl键被按下MK_LBUTTON/鼠标左键被按下MK_RBUTTON/鼠标右键被按下MK_SHIFT/Shift键被按下例如:“MK_SHIFT|MK_LBUTTON”表示同时按下了Shift键和鼠标左键。第10章VisualC+编程实例10.3 对话框的应用对话框的应用 对话框是一些弹出式窗口信息的弹出式窗口。它通常包含,应用程序利用它可和用户进行交互式操作。对话框是应用程序,用于显示或提示并等待用户输入一个或多个控件,利用这些控件,用户可以输入文本、选择选项,并完成某一特定命令。第
40、10章VisualC+编程实例对话框分为模式对话框和非模式对话框两种。模式对话框是指这种对话框出现时,它的父窗口将暂时失效,只有处理完对话框所要求的动作后,才会将控制权交回给父窗口。非模态对话框图类似普通的窗口,并不垄断用户的输入。在非模式对话框打开时,用户随时可用鼠标点击等手段激活其它窗口对象,操作完毕后再回到本对话框。本节只通过一个实例来介绍模式对话框。图10-3是用AppWizard生成的一个基于对话框的程序运行界面。下面详细介绍它的实现步骤:第10章VisualC+编程实例图10-3第10章VisualC+编程实例1.产生对话框模板在 VC+ 6.0中 选 择 菜 单 “File”“N
41、ew”或 按 【Ctrl+N】键,弹出一个对话框,如图10-4所示。在对话框中选择工程标签页,用鼠标选中左边列表框中的“MFCAppWizard【exe】”一行;在“C位置:”处输入存放源代码的目录的名字,单击“确定”后出现图10-5所示对话框。第10章VisualC+编程实例图10-4第10章VisualC+编程实例图10-5第10章VisualC+编程实例2.设置对话框模板设置对话框模板一般需要以下几步:设置对话框的属性;向对话框模板放置控件;通过控件属性对话框设置各个控件的属性和控件的跳表顺序。1)设置对话框的属性首先调整模板的大小:把鼠标放在对话框模板的边或角上,等鼠标变为双箭头形状,
42、拖动鼠标即可。点击对话框模板(而不是它上面某一控件),按【Enter】键弹出属性设置对话框,图10-6所示为该对话框的General页。可以设置对话框的风格和各边界滚动条的类型,对话框的标题等。第10章VisualC+编程实例图10-6第10章VisualC+编程实例2)添加控件并设置控件属性添加控件要借助于控件工具条(图10-7所示),控件工具条提供了25种控件。常用的控件是:图形控件(Picture)、静态文本框(StaticText)、编辑框(EditBox)、组框(GorupBox)、按钮(Botton)、复选框(CheckBox)和单选框(RadioButton)。图形控件用于显示位
43、图(Bitmap)和图标(Icon);静态文本框用于显示静态文本(当然显示的内容可以通过程序改变);编辑框用于数据的输入和显示;组框用于把若干控件从视觉上组合成一组,形成友好的界面;按钮用于用户向程序提供命令;复选框完成开关功能;单选框也提供选择,它与复选框的区别是在一组单选框中,用户只能选择其中一个,并且单选框自已不能取消自已的选择,而只能通过选中别的单选框来取消。第10章VisualC+编程实例图10-7第10章VisualC+编程实例向对话框增加一个控件的方法是在控件工具条上通过单击选择一个控件,然后在对话框模板上按下鼠标左键,控件就会按默认大小放置在对话框上。通过单击选中控件,把鼠标光
44、标移动到控件边缘,等光标呈箭头状时拖动鼠标可以改变控件的大小。删除一个控件的方法是先选中控件后按【Delete】键。设置控件的属性:先选中控件,按【Enter】键(或者按鼠标右键,在弹出的菜单上选择Properties项)弹出图10-8所示的属性对话窗口,在该窗口中可以设置控件的标识符(ID),标题(Caption)和各种风格(Style)等。第10章VisualC+编程实例图10-8第10章VisualC+编程实例在图10-9中,将对话框模板上的“TODO:在这是设置对话控制”静态文本框和“确定”按钮删除。为对话框增加3个编辑框,它们的ID分别为ID_EDIT_ADD1,ID_EDIT_AD
45、D2和ID_EDIT_ADD3;添加两个静态文本框,它们的Caption分别为“+”和“=”。另外,“+”和“=”的属性页对话框的Styles属性页要作两点改变:将“X对齐文本”属性设为Center,选择“C中垂直”复选框,如图10-10所示。第10章VisualC+编程实例图10-9第10章VisualC+编程实例图10-10第10章VisualC+编程实例再添加两个命令按钮,它们的Caption分别为“计算结果”和“退出”,“计算结果”的ID是IDC_BUTTON1,“退出”的ID是IDC_BUTTON2。3)定义成员变量增加了3个编辑框后,获取三个编辑框中的输入数字的常用方法是:先定义一
46、些与控件相联系的变量,然后在程序中通过这些变量来完成对控件的控制。为控件定义变量最方便的方法是通过ClassWizard。按 【 Ctrl+W】 键 , 弹 出 图 10-11所 示 的 MFCClassWizard对话框,选择MemberVariables窗口如图10-12所示。第10章VisualC+编程实例图10-11第10章VisualC+编程实例图10-12第10章VisualC+编程实例选中“IDC_EDIT1”,双击鼠标或单击AddVariable.按钮,弹出图10-13所示的对话框,这个对话框用来增加与控件相联系的成员变量。先为变量取名为m_add1,填在Membervaria
47、blename中。这个变量用来存放用户在IDC_EDIT1编辑框中输入的数,供程序计算结果用;再选择变量的类别填在Category中,可以为Value或Control,后者表示所定义的变量是控件类的一个对象,比如对于编辑框而言,Control类变量的类型是Cedit,前者表示所定义的变量是与控件相联系的一个值,第10章VisualC+编程实例这个值的含义随不同类型的控件而不同,如对于编辑框而言,变量表示在编辑框所输入的内容。有的控件不能定义与之相关的Value变量,如按扭;最后选择变量的类型填在Variabletype中,变量m_add1的类型定义为double类型。用同样的方法可以为其它控件
48、增加变量,最终增加的所有变量如下:IDC_EDIT1,double,a_add1IDC_EDIT2,double,a_add2IDC_EDIT3,double,a_add3第10章VisualC+编程实例图10-13第10章VisualC+编程实例4)增加事件处理函数在程序中希望点击图10-3中的命令按钮“计算结果”时,会将输入的两个数的和填入第3个编辑框。要想实现以上操作,必须为“计算结果”这个命令按钮填加鼠标左键单击命令按扭的处理函数。这样当鼠标左键单击这个事件发生时,就会执行这个处理函数。增加事件处理函数有两种方法:(1)通过专门的事件处理对话框第10章VisualC+编程实例(2)可以
49、在10-11窗口中所示的ClassWizard的MessageMaps标签页为控件添加事件处理函数。下面介绍第1种方法:选中图10-3中“计算结果”按钮,单击鼠标右键,在弹出菜单中选择Events,弹出的对话框如图10-14所示。第10章VisualC+编程实例图10-14第10章VisualC+编程实例此窗口用于添加、删除窗口的消息和事件处理函数。本程序需为按钮增加单击事件处理函数:双击左边列表框中的“BN_CLICKED”(这时会弹出一个对话框让用户修改事件处理函数的名字,若保持默认的名字,直接单击“确定”即可)。添加完单击事件处理函数后的对话框如图10-15所示,注意到增加了处理函数的事
50、件名移动到了右边的列表框中,在图10-15中单击EditExisting按钮可以直接进入对话框的源文件(.CPP),并为事件响应函数增加代码。第10章VisualC+编程实例图10-15第10章VisualC+编程实例因为添加的函数全都是空的,所以需要手工添加代码来实现用户想要的功能。在下面的程序中有一个函数UpdateData()出现了两次,其格式为:BOOLUpdateData(BOOLbSaveAndValidate=TRUE);UpdateData函数是MFC中的CWnd类的成员函数,CWnd类是很重要的MFC类,所有窗口类都直接或间接地继承于它。本程序主对话窗口类ClitleAdde
51、rDlg继承了Cdialog,而Cdialog又继承了CWnd,因此可以在程序中使用函数UpdateData。第10章VisualC+编程实例用户在程序运行过程中通过鼠标或键盘修改了对话框控件的状态后,对话框中与控件相关联的变量值并没有马上更新。以参数TRUE调用函数UpdateData()的作用就是更新所有与对话框图控件相关联的变量值,而以参数FALSE调用此函数则更新与变量相关联的控件的显示状态,使之与变量一致。也可以通俗地说,以TRUE和FALSE作为参数可分别实现控件关联变量的“里传”和“外传”。下面的语句起刷新编辑框的作用。第10章VisualC+编程实例voidCSf1Dlg:BU
52、TTON1()/TODO:Addextravalidationhere(在这里增加用户代码)UpdateData(true);m_add3=m_add1+m_add2;UpdateData(false);第10章VisualC+编程实例各关联变量的初值在函数CSf1Dlg:CSf1Dlg(它是程序主对话框类的构造函数)中初始化,它是由程序自动生成的。如果想修改某些变量的初值,可以在源程序中找到该函数,修改某些变量的初始值。即CSf1Dlg:CSf1Dlg(CWnd*pParent/*=NULL*/):CDialog(CSf1Dlg:IDD,pParent)第10章VisualC+编程实例/AF
53、X_DATA_INIT(CSf1Dlg)m_add1=0.0f;m_add2=0.0f;m_add3=0.0f;/AFX_DATA_INIT/ Note that LoadIcon does not require a subsequentDestroyIconinWin32m_hIcon=AfxGetApp()-LoadIcon(IDR_MAINFRAME);第10章VisualC+编程实例到此本程序编制完成,可以按【Ctrl+F5】键看它的运行结果。本程序并不是很完善,但作者仅仅是想通过这个例子告诉读者简单的对话窗口是如何编制的。如果读者感兴趣,你可以试着增加一些控件或功能使它更加完善。第
54、10章VisualC+编程实例10.4 菜菜 单单 的的 应应 用用菜单是一个专业程序不可缺少的程序界面构件,对于不同的程序,这些构件会以不同的面貌出现。菜单是Windows使用者天天都要见到的应用元素。第10章VisualC+编程实例菜单由上层水平列表项及与其相连的弹出式菜单项组成,用户选择了上层某个列表项时,与之相连的弹出式菜单就会随即出现。菜单的各个菜单项用来响应用户的鼠标单击而产生命令消息,从而提供一种用户对程序进行控制的方式。由于弹出式菜单平时是隐藏的,只露出上层水平列表项,因此菜单能容纳大量的操作。第10章VisualC+编程实例菜单也是一种资源,因此要通过DeveloperStu
55、dio的资源编辑器编辑。“弹出式菜单”、“选项”和“分隔线”是构成“树状菜单”的三大要素。通过“弹出式菜单”可以调出一个子菜单,分隔线用来区分一组选项。通过菜单中的“选项”可以调用应用程序的某项功能。每个选项均有一个标识符,而且只有选项才有标识符。在应用程序中只对选项编程。当用户选择了一个菜单选项后,就会向应用程序发送一个命令消息WM_COMMAND。该消息的格式为ON_COMMAND(id,memberFxn)第10章VisualC+编程实例1.编辑菜单选择“插入”“资源”菜单项或按【Ctrl+R】键,在弹出的添加资源对话框中选择“菜单”,然后按【Enter】键,即可向项目添加一个菜单资源。
56、这时,菜单资源编辑器打开,菜单编辑器的窗口如图10-16所示。其中,灰色的横条是菜单,周围有一个白框的灰色块是要添加的菜单项。下面分几步编辑菜单:第10章VisualC+编程实例图10-16第10章VisualC+编程实例图10-17第10章VisualC+编程实例1)添加菜单上层水平列表项单击选中要添加的菜单项小灰块,按【Enter】键弹出其属性对话框(如图10-7所示),上层水平列表项是具有弹出属性的菜单项,它没有ID,它的“C标题”是菜单上显示的字符串,也叫菜单的名字。在图中的“C标题”处输入了字符串“文件(&F),当程序运行时界面上将显示“文件(F)(字符&并不显示出来),实际上,字符
57、&的作用是使紧跟在它后面的字符下面加下划线。这样按【Alt+V】键可激活此菜单项,这是利用键盘选择菜单项的一种方法。第10章VisualC+编程实例2)添加各上层水平列表项的子菜单项单击已经添加的某一个水平列表菜单项,其下面会出现一个空的菜单项,选中这个空的菜单项,按【Enter】键弹出要新加子菜单的属性对话框,在对话框中输入菜单项的ID和Caption,然后设置菜单的其它属性。有时希望把功能相近的菜单项放在一起成为一组,通过一个横的分割线把它与其它菜单项分割开。产生一条分割线的方法是在菜单项的属性对话框中选择“分隔符”复选框。第10章VisualC+编程实例图10-18第10章VisualC
58、+编程实例2.为菜单单击增加消息响应函数1)方法一设置好菜单的各个菜单项后,就可用ClassWizard为菜单增加消息响应函数了。(通过按【Ctrl+W】键)弹出ClassWizard对话框后,选择ClassWizard的MessageMaps页(如图10-19所示)第10章VisualC+编程实例图10-19第10章VisualC+编程实例在图10-19中的Project和Classname组合框中分别选择要为哪个项目的哪个类增加消息响应函数,所以Project 中选择“Menutest和Class name组合框中选择“CmenuTestView。在ObjectIds列表框中选中一个菜单I
59、D(比如ID_TEST_COMMAND),可以为这个ID的菜单增加单击响应函数,方法是:选中右边Message列表框中的COMMAND行,单击Add Function.(或双击COMMAND行),在弹出的对话框中单击OK按钮。用同样的操作为所有菜单项增加单击响应函数。最后单击ClassWizard对话框的“确定”按钮来确认添加(或者单击editCode按钮直接跳到源文件为函数增加实现代码)。第10章VisualC+编程实例例10.2在单文档界面的应用程序中,添加一个“画图”菜单项包括“画矩形”和“画圆形”,并添加不同的颜色。第一步:创建一个基于单文档界面的应用程序,将工程命名为MenuTest
60、(参照1.3.2节的步骤)第二步:在“工程管理区”中点击“ResourceView”,在Menu文件夹中选择“IDR_MAINFRAME”,双击菜单中添加一个菜单,如图10-20所示。菜单项“画矩形”的ID标识为“ID_RECT_COMMAND”。菜单项“画圆形”的ID标识为“ID_CIRCLE_COMMAND”。第10章VisualC+编程实例第三步:为“画图”菜单项添加消息响应函数。按【Ctrl+w】键弹出如图10-21的窗口,选择“Pojec为工程名“MenuTest”,选择“Classname为“CmenuTestView”,选择“ObjectIds:”为画矩形的标识“ID_RECT_
61、COMMAND”,选中右边Message列表框中的COMMAND行,单击AddFunction.(或双击COMMAND行),在弹出的对话框中单击OK按钮。用同样的操作为“画圆形”菜单项增加单击响应函数。最后单击ClassWizard对话框的“确定”按钮来确认添加(或者单击EditCode按钮直接跳到源文件为函数增加实现代码)。第10章VisualC+编程实例图10-20第10章VisualC+编程实例图10-21第10章VisualC+编程实例两个菜单项的响应函数为:voidCMenuTestView:OnRectCommand()/TODO:Addyourcommandhandlercode
62、here(在这里加入命令处理代码)CClientDCdc(this);CBrushbrushNew;CPenpenNew;brushNew.CreateSolidBrush(RGB(255,0,0);penNew.CreatePen(PS_SOLID,1,RGB(255,0,0);dc.SelectObject(&brushNew);第10章VisualC+编程实例dc.SelectObject(&penNew);dc.Rectangle(20,20,200,180);voidCMenuTestView:OnCircleCommand()/TODO:Addyourcommandhandlerc
63、odehere(在这里加个命令处理代码)CClientDCdc(this);CBrushbrushNew;CPenpenNew;第10章VisualC+编程实例brushNew.CreateSolidBrush(RGB(0,0,255);penNew.CreatePen(PS_SOLID,1,RGB(255,0,0);dc.SelectObject(&brushNew);dc.SelectObject(&penNew);dc.Ellipse(280,20,460,200);分析:首先生成一个CclientDC类型的对象dc,Cclient继承了设备上下文类CDC。CDC用于指定设备上下文(如窗
64、口客户区、打印机)进行绘图、显示文本等操作,而CclientDC用于在窗口客户区画图和显示文本。第10章VisualC+编程实例BrushNew.CreateSolidBrush()是用于设置画刷的颜色,penNew.CreatePen()是用于设置画笔的颜色,dc.Ellipse()是画椭圆的函数。代码输入完成后,按Ctrl+F5键开始运行,运行结果如图10-22所示。第10章VisualC+编程实例图10-22第10章VisualC+编程实例2)方法二(1)载入菜单的工作可以在CWnd类的PreCreateWindow()函数中进行,其原型为virtualBOOLPreCreateWind
65、ow(CREATESTRUCT&cs);其中,参数cs的类型为CREATESTRUCT。该类型用于存放建立窗口的初始化参数。PreCreateWindow()函数在窗口创建前被调用,通过重载该函数,可以设置各种窗口参数,也可以使用LoadMenu()载入菜单资源。其代码为:cs.hMenu=LoadMenu(NULL,MAKEINTRESOURCE(IDR_mAINMENU);第10章VisualC+编程实例(2)为每个菜单选项添加消息映射WM_COMMAND()和消息处理成员函数。例10.3在窗口中显示一个位图文件,设计一个菜单,使图像能放大、缩小和正常显示。#include#include
66、resource.h/框架窗口类classCMyWnd:publicCFrameWnd第10章VisualC+编程实例CBitmapm_Bitmap;floatm_fTimes;intm_nHeight;intm_nWidth;public:CMyWnd();BOOLPreCreateWindow(CREATESTRUCT&cs);protected:第10章VisualC+编程实例afx_msgvoidOnShrink();afx_msgvoidOnBestFit();afx_msgvoidOnZoomOut();afx_msgvoidOnPaint();DECLARE_MESSAGE_MA
67、P();/消息映射BEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd)ON_WM_PAINT()第10章VisualC+编程实例ON_COMMAND(ID_SHRINK,OnShrink)ON_COMMAND(ID_BESTFIT,OnBestFit)ON_COMMAND(ID_ZOOMOUT,OnZoomOut)END_MESSAGE_MAP()/主窗口类的成员函数CMyWnd:CMyWnd()BITMAPBM;m_Bitmap.LoadBitmap(IDB_BITMAP1);/载入位图资源第10章VisualC+编程实例m_Bitmap.GetBitmap(&BM);/读
68、位图信息m_nWidth=BM.bmWidth;m_nHeight=BM.bmHeight;m_fTimes=1.0;/装入菜单BOOLCMyWnd:PreCreateWindow(CREATESTRUCT&cs)第10章VisualC+编程实例cs.hMenu=LoadMenu(NULL,MAKEINTRESOURCE(IDR_MENU1);returnCFrameWnd:PreCreateWindow(cs);/缩小图像voidCMyWnd:OnShrink()m_fTimes=0.5;Invalidate();/放大图像第10章VisualC+编程实例voidCMyWnd:OnZoomO
69、ut()m_fTimes=2.0;Invalidate();/正常显示voidCMyWnd:OnBestFit()m_fTimes=1.0;Invalidate();/响应绘制窗口客户区消息第10章VisualC+编程实例voidCMyWnd:OnPaint()CPaintDCdc(this);CDCMemDC;MemDC.CreateCompatibleDC(NULL);MemDC.SelectObject(&m_Bitmap);/CDC类的成员函数,用来显示位图资源dc.StretchBlt(0,0,(int)(m_nWidth*m_fTimes),(int)(m_nHeight*m_fT
70、imes),&MemDC,0,0,m_nWidth,m_nHeight,SRCCOPY);第10章VisualC+编程实例/应用程序类classCMyApp:publicCWinApppublic:BOOLInitInstance();/应用窗口类的成员函数/初始化应用程序实例第10章VisualC+编程实例BOOLCMyApp:InitInstance()CMyWnd*pFrame=newCMyWnd;pFrame-Create(0,_T(ShowBitmap1.0);pFrame-ShowWindow(SW_SHOWMAXIMIZED);pFrame-UpdateWindow();this
71、-m_pMainWnd=pFrame;returnTRUE;CMyAppThisApp;/全局应用程序对象第10章VisualC+编程实例调试:首先建立Win32Application空白项目和源程序代码文件,然后为项目添加建立资源文件。建立资源文件的方法如下:l使用菜单项“文件”“新建”,从文件选项卡中选择“ResourceScript(资源描述)”,并在选项卡右方添入资源文件名(通常与项目名相同)后按“确定”键。此时即可发现在工作区窗口中新添了一个ResourceView,通过它可以查看项目中的各种资源。第10章VisualC+编程实例l 选择菜单选项“插入”“资源”,调出“Insert
72、Resource对 话 框 , 然 后 在 其 中 选 择 相 应 的 资 源“Bitmap(位图)”和“Menu(菜单),再选择选项卡右边的“导入”按钮,弹出一个窗口选择位图文件所在的路径和文件名,再按“Import”按钮,则所选的位图文件会插入到工作区窗口的“ResourceView”中并显示出来,再如前所述,在菜单中添加菜单项和标识符ID。至些,资源文件便建好了,再输入源程序代码,然后按【Ctrl+F5】开始运行程序。运行结果如图10-23所示。第10章VisualC+编程实例图10-23第10章VisualC+编程实例10.5 工工 具具 栏栏 应应 用用 工具条是一种重要的控制条,是
73、一个包含按扭、列表框或其它控制的子窗口。大多数工具条是一行用于激活命令的位图化的按钮。按一个工具条按钮类似于选择一个菜单项。这些按钮可以起命令按钮、复选框和单选钮的作用。第10章VisualC+编程实例图10-24第10章VisualC+编程实例工具条的特点:通常排列在框架窗口的顶部,随着用户在工具条的按钮上移动鼠标,工具条还可以在按钮附近显示“工具提示”。若在MFCAppWizardStep4of6中设置了“Dockingtoolbar选项,则AppWizard自动生成一个缺省的工具条,如图10-24所示。该工具条为APPWizard生成的标准Windows菜单提供了另外一种快捷操作。若项目
74、中没有工具条,可采用这种方法加入:选择“插入”“资源”菜单项或按【Ctrl+R】键,在弹出的添加资源对话框中选择“ToolBar”,然后按【Enter】键,即可向项目添加一个工具条资源。这时,工具条资源编辑器打开,菜单编辑窗口如图10-25所示。第10章VisualC+编程实例图10-25第10章VisualC+编程实例工具条编辑器实际是一个图像编辑器,利用绘图面板上的各种绘图工具和在颜色面板选择各种颜色可以绘制一些简单的图形和图像。增加一个工具条按钮:最初工具条上只有一个待定制的按钮,但只要利用绘图面板上的任何一种工具对这个按钮进行了处理,工具条上马上出现另一个按钮待定制,也就是说,始终有一
75、个待定制的按钮在工具条的最右边,它的作用仅仅是增加按钮,在程序运行时不会出现。一个工具条中所有按钮的图形放在一个位图中,而该位图定义在应用程序的资源文件中,当工具条中的按钮被按下时,它会发送相应的命令消息(与菜单类似)。第10章VisualC+编程实例修改工具条的属性:在WorkSpace窗口的ResourceView页中Toolbar文件夹下面的工具条名字(IDR_TOOLBAR)上按【Alt+Enter】(或按鼠标右键),弹出工具条的属性对话框,如图10-26所示。工具条中的按扭常常对应于常用的菜单项命令,因而只需将“按扭”数组中的ID置为相应的菜单项命令ID,就可实现工具条按钮和菜单项命
76、令执行同一代码段。与此对应,应用程序能对任何命令消息作出响应,并将其发送给同一处理函数处理,而不论消息来自菜单项还是来自工具条按钮。第10章VisualC+编程实例图10-26第10章VisualC+编程实例小结本章讲述了基于对话框的应用程序的基本编程思路、基于单文档编程的菜单设计和工具栏设计的基本方法。1.首先介绍基于对话框的应用程序编程的工作流程,然后介绍了一个吹彩色泡泡的实例,讲述了相关的一些函数和常用的MFC类库的成员函数。2.讲述了基于对话框的应用程序的实例。主要讲述了设计一个简单的对话框用户界面的步骤。3.讲述了菜单的概念和设计一个菜单的步骤。4.讲述了工具栏的设计步骤。第10章VisualC+编程实例部分资料从网络收集整理而来,供大家参考,感谢您的关注!