MFC原理与方法

上传人:鲁** 文档编号:570207091 上传时间:2024-08-02 格式:PPT 页数:130 大小:5.70MB
返回 下载 相关 举报
MFC原理与方法_第1页
第1页 / 共130页
MFC原理与方法_第2页
第2页 / 共130页
MFC原理与方法_第3页
第3页 / 共130页
MFC原理与方法_第4页
第4页 / 共130页
MFC原理与方法_第5页
第5页 / 共130页
点击查看更多>>
资源描述

《MFC原理与方法》由会员分享,可在线阅读,更多相关《MFC原理与方法(130页珍藏版)》请在金锄头文库上搜索。

1、MFCMFC原理与方法原理与方法采用MFC编程的优点使用标准化的程序代码结构,有利于程序员之间的交流。VisualC+为MFC提供了大量的工具支持,提高了编程效率。如利用MFCAppWizard创建MFC应用程序框架,利用ClassWizard方便地对Windows消息进行管理。MFC应用程序的效率较高,只比传统的WindowsC程序低5%左右。并且,在MFC应用程序中还允许混合使用传统的WindowsAPI函数。其它优势:完全支持Windows所有的函数、控件、消息、菜单及对话框;具有良好的稳定性和可移植性,更符合微软的风格等。MFC体系结构MFC主要组成部分:类、宏和全局函数。类是MFC中

2、最主要的内容。MFC类是以层次结构方式组织起来的。MFC中的类分成两部分,除了一些辅助类,大多数的MFC类是直接或间接从根类CObject派生而来。几乎每一个派生层次都与一具体的Windows实例相对应,如文档类、窗口类和视图类等。MFC宏主要功能:消息映射、运行时对象类型服务、诊断服务、异常处理。MFC约定:全局函数以“Afx”为前缀,全局变量以“afx”为前缀。学习MFC的方法首先要对Windows编程概念和API函数有一定的了解,如WindowsAPI有哪些功能和哪些常用的数据结构等。学会抽象地把握问题,不求甚解,不要一开始学习VisualC+就试图了解整个MFC类库。从理解和使用两个方

3、面学习MFC,理解MFC应用程序的框架结构。先大体上了解MFC的概念、组成和基本约定,从简单的类入手,结合程序设计,由浅入深,循序渐进、日积月累。编程时如果MFC某个类能完成所需要的功能,可以直接调用已有类的方法(成员函数)。否则,可以利用面向对象技术中的“继承”方法对MFC类的行为进行扩充和修改,从MFC中已有的类派生出自己需要的类。学习MFC,另一点就是不要过分依赖于向导(Wizard)工具。向导能做许多工作,但同时掩饰了太多的细节。MFC应应用用程程序序生生成成MFC中的常用类CObject、CCmdTarget、CWinThread、CWinApp、CWnd、CFrameWnd、CDi

4、alog、CView、CStatic、CButton、CListBox、CComboBox、CEdit、CScrollBarMFC中的大部分类都是从基类CObject中继承的,该类包含大部分MFC类所通用的数据成员和成员函数;CWinApp类是在建立应用程序时需要用到的,并且在任何程序中都只用一次;CWnd类汇集了Windows中的所有通用特性、对话框和控制。CFrameWnd类是从CWnd中继承的,并实现了标准的框架应用程序;CDialog可分别处理无模式和有模式两种类型的对话框。CView用于让用户通过窗口来访问文档。在MFC应用程序的CWinApp派生类对象theApp是一个全局变量,代

5、表了应用程序运行的主线程。它在程序整个运行期间都存在,它的销毁意味着运行程序的消亡。MFC应用程序启动时,首先创建应用程序对象theApp,这时将自动调用应用程序类的构造函数初始化对象theApp,然后由应用程序框架调用MFC提供的AfxWinMain()主函数。AfxWinMain()主函数首先通过调用全局函数AfxGetApp()获取应用程序对象theApp的指针pApp,然后通过pApp调用应用程序对象的有关成员函数,完成程序的初始化和启动工作,最后调用成员函数Run(),进入消息循环。程序运行后将收到WM_PAINT消息,调用OnPaint()函数绘制客户区窗口。如果Run()收到WM

6、_QUIT消息,则结束消息循环,然后调用函数ExitInstance(),结束程序运行。MFC应用程序的生与死应用程序的生与死 hello程序流程 MFC应用程序对象之间的关系应用程序对象之间的关系 MFC应用程序运行后各函数的调用关系应用程序运行后各函数的调用关系 InitInstance()函函数数是是派派生生类类唯唯一一需需要要重重载的函数,它负责应用程序的初始化。载的函数,它负责应用程序的初始化。CWinApp类CWinApp类提供了用户与Windows应用程序之间进行交流的接口。在生成类的对象后,对象自动建立与Windows系统的连接、接收Windows传送的消息,并交给程序中相应的

7、对象去处理,这就免去了程序员的许多工作,使得开发C+的Windows程序变得简单方便。CWinApp类的对象theApp将自动创建一个主线程,主线程中有一个循环体,用来不断的从应用消息队列中提取消息,并发送回操作系统,让操作系统调用窗口过程函数,实现消息响应。CWinApp类通过消息映射宏的方式,方便开发人员完成消息与响应函数之间的对应关系,大大简化了编程难度与复杂度。CMainFrame类类CMainFrame是由MFC中的CFrameWnd派生的,所以它也是一个框架窗口。CMainFrame是类CXXView的父类,即CXXView类的对象显示在主框架窗口的客户区中。在类CMainFram

8、e中,系统已经从类CFrameWnd中继承了处理窗口的一般事件的Windows消息,如改变窗口的大小、窗口最小化等的成员函数,因此编程时程序员不必关心此类消息的处理,从而减轻了程序员的负担。当然,如果确实需要重新编写此类消息的成员函数,则需要对原有的成员函数进行重载。当程序的一个实例被运行时,系统将根据前面在CWinApp类中介绍的文档模板对象自动生成类CMainFrame、CXXView、CXXDoc的对象,而不需要程序员主动地去创建这些类的对象。类CXXView与CXXDoc这两个类是密切相关的,文档是由文档模板对象生成的,并由应用程序对象管理,而用户则是通过与文档相联系的视窗对象来存储、

9、管理应用程序中的数据,用户与文档之间的交互是通过与文档相关联的视窗对象进行的。生成一个新的文档时,MFC程序同时生成一个框架窗口,并且在框架窗口的客户区中生成一个视窗对象作为框架窗口的子窗口,这个子窗口以可视化的方式表现文档中的内容。视窗的重要功能就是负责处理用户的鼠标、键盘等操作,通过对视窗对象的处理达到处理文档对象的目的。MFC通用控件类和窗口类绘图类CClientDC类:一般用来方便地创建和销毁一个设备环境。CClientDC通常在堆栈上创建。析构函数自动调用ReleaseDC(),不会导致内存资源泄漏.CWindowDC类:与CClientDC类相似,但它的工作范围是窗口的非客户区。C

10、PaintDC类:仅允许绘制无效的窗口客户区而不是绘制整个窗口,CWnd:BeginPaint()与CWnd:EndPaint()配对使用;CMetaFileDC类:用于创建元文件,元文件是一种磁盘文件,它包含了所有的绘图行为以及绘制图像所需要的绘图模式。常用的MFC文件和库文件 文文 件件 名名 称称说说 明明afxwin.h声明声明MFC核心类核心类afxext.hMFC扩展文件,声明工具栏、状态栏、拆分窗口等类扩展文件,声明工具栏、状态栏、拆分窗口等类afxdisp.h声明声明OLE类类afxdtctl.h声明支持声明支持IE 4公用控件的公用控件的MFC类,如类,如CImageList

11、等等afxcmn.h声明声明Windows公共控件类公共控件类Mfc42.libMFCxx.DLL的导入函数库(的导入函数库(Release版)版)Mfc42D.libMFCxx.DLL的导入函数库(的导入函数库(Debug版)版)MfcS42.libMFCSxx.DLL的导入函数库(的导入函数库(Static Release版)版)MfcS42D.libMFCSxxD.DLL的导入函数库(的导入函数库(Static Debug版)版)Mfc42U.libMFCxxU.DLL的导入函数库(的导入函数库(Unicode Release版)版)Mfc42UD.libMFCxxUD.DLL的导入函数

12、库(的导入函数库(Unicode Debug版)版)MfcO42D.libMFCOxxD.DLL的导入函数库(的导入函数库(OLE Debug版)版)MfcD42D.libMFCDxxD.DLL的导入函数库(的导入函数库(Database Debug版)版)Nafxcw.libMFC静态链接库(静态链接库(Release版)版)NafxcwD.libMFC静态链接库(静态链接库(Debug版)版)gdi32.libGDI32.DLL的导入函数库的导入函数库user32.libUSER32.DLL的导入函数库的导入函数库kernel32.libKERNEL32.DLL的导入函数库的导入函数库ms

13、vcrt.libMSVCRT.DLL(C运行函数库)的导入函数库运行函数库)的导入函数库msvcrtd.libMSVCRTD.DLL(Debug版版C运行函数库)的导入函数库运行函数库)的导入函数库libcmt.libC运行函数静态链接库(多线程)运行函数静态链接库(多线程)libc.libC运行函数静态链接库(单线程)运行函数静态链接库(单线程)进入下一节进入下一节MFC消息管理 MFC应用程序消息处理的方式与SDK应用程序有所不同。MFC应用程序框架截取了Windows向应用程序发出的消息,再确定将消息发送给哪一个对象,可以根据需要利用函数重载对消息进行处理,但不需要处理的消息将由应用程序

14、框架自动处理。消息管理包括消息的发送和处理。对于消息发送,MFC提供了类似于API函数功能的消息发送函数,而MFC消息处理的内部机制则相对复杂一些。从编程的角度出发,我们只需了解其大致的原理。MFC的消息分类标标 准准 Windows消消 息息 : 以以 WM_前前 缀缀 ( 但但 不不 包包 括括WM_COMMAND)开开始始的的消消息息,包包括括鼠鼠标标消消息息、键键盘盘消消息息和窗口消息,如和窗口消息,如WM_MOVE 、WM_PAINT等。等。控控件件通通知知(Control Notification)消消息息:对对控控件件操操作作引引起起的的消消息息,是是控控件件和和子子窗窗口口向向

15、其其父父窗窗口口发发出出的的WM_COMMAND通通知知消消息息。例例如如,当当用用户户修修改改了了编编辑辑控控件件中中的的文文本本后后,编编辑辑控件向其父窗口发送控件向其父窗口发送WM_COMMAND通知消息通知消息。命命令令(Command)消消息息:由由菜菜单单项项、工工具具栏栏按按钮钮、快快捷捷键键等等用用户户界界面面对对象象发发出出的的WM_COMMAND消消息息。命命令令消消息息与与其其它它消消息息不不同同,它它可可被被更更广广泛泛的的的的对对象象如如文文档档、文文档档模模板板、应用程序对象、窗口和视图等处理。应用程序对象、窗口和视图等处理。 自定义消息自定义消息MFC消息映射机制

16、 MFC采用消息映射(MessageMap)机制取代C/C+语言中的switch-case结构来处理消息。MFC消息映射机制包括一组消息映射宏,一条消息映射宏把一个Windows消息和其消息处理函数联结起来。在类定义的结尾用DECLARE_MESSAGE_MAP()宏来声明使用消息映射。在 类 的 实 现 源 文 件 中 用 BEGIN_MESSAGE_MAP()和 END_MESSAGE_MAP()宏来定义消息映射。ON_COMMAND宏:消息映射宏的第一个参数为消息ID,第二个参数为消息处理函数。 如ON_COMMAND(ID_FILE_NEW,CWinApp:OnFile New)。MF

17、C使用ClassWizard帮助实现消息映射功能。例子:例子:v在AppWizard产生的应用程序类的源码中,应用程序类的定义(头文件)包含了类似如下的代码:/AFX_MSG(CTttApp)afx_msgvoidOnAppAbout();/AFX_MSGDECLARE_MESSAGE_MAP()v应用程序类的实现文件中包含了类似如下的代码:BEGIN_MESSAGE_MAP(CTApp,CWinApp)/AFX_MSG_MAP(CTttApp)ON_COMMAND(ID_APP_ABOUT,OnAppAbout)/AFX_MSG_MAPEND_MESSAGE_MAP()v头文件里是消息映射和

18、消息处理函数的声明,实现文件里是消息映射的实现和消息处理函数的实现。它表示让应用程序对象处理命令消息ID_APP_ABOUT,消息处理函数是OnAppAbout。MFC应用程序MESSAGE_MAP消息映射形式BEGIN_MESSAGE_MAP(theclass, baseclass)/AFX_MSG_MAP(theclass)ON_ . . . . . . /MFC预定义的消息映射宏ON_MESSAGE(message , memberFxn) /用户自定义的消息映射宏./AFX_MSG_MAPEND_MESSAGE_MAP()注注意意:特特殊殊注注解解“/“/AFX_MSG_MAP”AFX

19、_MSG_MAP”是是ClassWizardClassWizard类类向向导导用用于于维维护护消消息息映映射射宏宏的的标标记记,用用户户不不要要删删除除注注解解轻轻易易修修改改注注解解内内的代码。的代码。 例 利用ClassWizard为框架类添加消息WM_CLOSE、WM_DESTROY及菜单项“Edit|Copy”的消息处理函数,分析ClassWizard完成了哪些工作。 启动ClassWizard,添加要求的三个消息处理函数,ClassWizard将在类的实现文件中添加三个消息映射宏和消息处理函数。消息映射宏如下:BEGIN_MESSAGE_MAP(CMainFrame,CFrameWn

20、d)/AFX_MSG_MAP(CMainFrame)ON_WM_CREATE()/由MFCAppWizard程序向导自动生成的消息映射ON_WM_CLOSE()/由ClassWizard类向导添加ON_WM_DESTROY()ON_COMMAND(ID_EDIT_COPY,OnEditCopy)/AFX_MSG_MAPEND_MESSAGE_MAP()ClassWizard在类的定义中声明了消息处理函数classCMainFrame:CFrameWndpublic:CMainFrame();protected:/AFX_MSG(CMainFrame) /声明消息处理函数原形afx_msgint

21、OnCreate(LPCREATESTRUCTlpCreateStruct);/由程序向导自动生成afx_msgvoidOnClose();/由ClassWizard类向导添加afx_msgvoidOnDestroy();afx_msgvoidOnEditCopy();/AFX_MSGDECLARE_MESSAGE_MAP()/声明使用消息映射宏;消息的发送发送消息到一个窗口可以采用传送(Send)或寄送(Post)方式,这两种方式之间的主要区别是消息被接收对象收到后是否立即被处理。Windows提供了三个API函数用于消息的发送。函数SendMessage()用于向一个或多个窗口传送消息,该

22、函数将调用目标窗口的窗口函数,直到目标窗口处理完收到的消息,该函数才返回。函数PostMessage()用于向一个或多个窗口寄送消息,它把消息放在指定窗口创建的线程的消息队列中,然后不等消息处理完就返回。函数SendDlgItemMessage()函数用于向对话框中指定的控件发送消息,直到目标控件处理完收到的消息,该函数才返回。MFC将这三个函数封装为CWnd窗口类的成员函数,封装了目标窗口句柄,它们将向调用它的窗口对象发送或寄送消息,如pMyView-SendMessage()的调用形式表示向pMyView所指对象发送消息。与用户输入相关的消息(如鼠标消息和键盘消息)通常是以寄送(Post)

23、的方式发送,以便这些用户输入可以由运行较缓慢的系统进行缓冲处理。而其它消息通常是以传送(Send)的方式发送。手工处理消息映射创建自己的消息映射的具体过程:定义自己的消息ID:MFC允许用户自定义消息,常量WM_USER(为0x0400)与第一个自定义消息值相对应,用户必须为自己的消息定义相对于WM_USER的偏移值。利用#define语句定义自己的消息,例如:#defineWM_USER0X0400#defineWM_USER1WM_USER+0#defineWM_USER2WM_USER+1是对应的消息处理函定定义义消消息息映映射射:在BEGIN_MESSAGE_MAP()之后,END_M

24、ESSAGE_MAP()之前加入消息映射语句:ON_MESSAGE(message,memberFxn)其中,message是消息名标识,memberFxn数。在在cppcpp文件中定义消息处理函数,对消息进行响应:文件中定义消息处理函数,对消息进行响应:自自定定义义消消息息处处理理函函数数的的声声明明:必须在函数返回类型前面加上afx_msg标识,如:afx_msgLRESULTmemberFxn(WPARAMwParam,LPARAMlParam);其中,参数wParam、lParam用于传递消息的两个附加信息。在在需需要要发发送送消消息息的的地地方方发发送送消消息息:可用CWnd:Sen

25、dMessage()函数或CWnd:PostMessage()函数发送消息。例 编写一个自定义消息应用程序,程序启动后设置一个定时器,在WM_TIMER的消息处理函数中发送一个用户自定义消息,在对应的自定义消息处理函数中以动画的形式旋转显示一行文本。 基本思路:基本思路:1.1.用用WM_TIMERWM_TIMER消息处理函数发送消息;消息处理函数发送消息;启动定时器启动定时器销毁定时器销毁定时器2.2.用自定义消息完成动画旋转显示功能。用自定义消息完成动画旋转显示功能。自定义消息自定义消息IDID定义消息映射定义消息映射定义消息处理函数定义消息处理函数具体过程:1首先利用MFCAppWiza

26、rdexe向导创建一个名为Rotate的应用程序。利用ClassWizard类向导为CRotateView类生成消息WM_CREATE的消息处理函数,通过设置定时器在指定的时间间隔向窗口发送WM_TIMER消息。SetTimer(1,200,NULL);/启动定时器2在文件RotateView.cpp开始位置定义一个用户自定义消息:#defineWM_MYMESSAGEWM_USER+1利 用 ClassWizard为 CRotateView类 生 成 消 息WM_TIME的消息处理函数:SendMessage(WM_MYMESSAGE);3在类CRotateView的定义中声明自定义消息处理

27、函数:afx_msgLRESULTOnMyMessage(WPARAMwParam,LPARAMlParam);在文件RotateView.cpp消息映射BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间添加自定义消息映射宏:ON_MESSAGE(WM_MYMESSAGE,OnMyMyessage)4在类CRotateView的定义中声明一个private属性、int型的成员变量m_dEscapement,它表示文本显示角度,并在类CRotateView的构造函数中初始化:m_dEscapement=0;5利用ClassWizard生成消息WM_DESTROY的消息处理函数

28、,在销毁已创建的定时器:KillTimer(1);6在文件RotateView.cpp中手工添加自定义消息处理函数实现代码,完成以动画形式旋转显示一行文本的功能。LRESULTCE6_6View:OnMyMessage(WPARAMwParam,LPARAMlParam)CClientDCdc(this);m_dEacapement=(m_dEacapement+100)%3600;CFontfontRotate;fontRotate.CreateFont(30,0,m_dEacapement,0,0,0,0,0,0,0,0,0,0,0);CFont*pOldFont=dc.SelectObj

29、ect(&fontRotate);CRectrClient;GetClientRect(rClient);dc.FillSolidRect(&rClient,RGB(255,255,255);dc.TextOut(rClient.right/2,rClient.bottom/2,不登高山不知天之高也);dc.SelectObject(pOldFont);return0;如果不考虑自定义消息,可以采用其他方式:如果不考虑自定义消息,可以采用其他方式:1.1.WM_TIMERWM_TIMER消息处理函数:消息处理函数:调用文本显示函数调用文本显示函数旋转变量的计算旋转变量的计算2.2.定义一个函数

30、用来显示文本定义一个函数用来显示文本3.3.定义一个变量用于文本的位置计算定义一个变量用于文本的位置计算进入下一节进入下一节第三章文档视图结构:MFC的三种窗体类型在MFC中,文档是真正的数据载体,视图是文档的显示界面,对应于同一个文档,可能存在多个视图界面,需要另外一种东西将界面管理起来,即框架。SDI单文档窗口:一次只处理一个文档,譬如记事本,绘图板;MDI多文档窗口:可同时处理多个文档,也意味着需要更多的额外编程工作。并不只是要跟踪所有打开的文档,还要提供Window菜单来管理特殊的程序特性;Dialog对话框窗口:通常只需要显示少量的数据和获取少量的用户输入,除了节省资源外,对话框版本

31、的应用程序的加载速度也更快些;文档和视图的四个核心类1.Cdocument(或COleDocument):该类负责存储和管理程序的数据,并为自定义的文档类提供基础的功能。一个文档代表一个数据单元,用户可以通过文件菜单上的“打开”命令打开文档,或通过文件菜单上的“保存”命令保存文档。2.Cview类或其派生类:该类为自定义的视图类提供了基础的功能。一个视图附加到一个文档并扮演一个文档和用户的中间人角色:视图显示文档的外观到屏幕上,并把用户的输入翻译成对文档的操作。此外,视图类还负责打印和打印预览的显示。CView最常用的函数是GetDocument,这个函数用于返回与此视图关联的文档。同时CVi

32、ew具有窗口类的功能,可以方便的定义消息处理函数,MFC定义了一个非常好的、在“文档-视图-框架”之间的消息传递机制。3.CFrameWnd类:该类支持一个文档的一个或多个视图的框架,框架窗口类定义了一个视图的容器。一个SDI程序只使用一个框架窗口CFrameWnd类作为程序的顶层窗口提供视图的框架。一个MDI程序使用两种不同类型的框架窗口CMDIFrameWnd作为顶层窗口,CMDIChildWnd作为浮动窗口,为程序文档提供框架。4.CDocTemplate(CSingleDocTemplate或CMultiDocTemplate):文档模板类支持某种类型的文档并管理这种类型的文档、视图和

33、框架窗口对象。文档模板为了管理创建文档、视图和框架窗口的复杂过程,MFC框架使用两种文档模板类:CSingleDocTemplate类为SDI(单文档)程序提供支持CMultiDocTemplate类为MDI(多文档)程序提供支持。一个CSingleDocTemplate类可以一次创建和存储一个类型的文档。文档对象由程序对象创建并维护,在程序的InitInstance方法中完成的一个关键任务是创建一个或多个适当类型的文档模板,程序对象为模板列表中的每个文档模板存储一个指针,提供一个接口用来添加文档模板。如果需要支持两个或更多的文档类型,就应该为每种文档类型添加一个AddDocTemplate的

34、调用。多文档和多视图文档-视图程序不仅局限在一个文档和基于文档数据的视图,通过使用MFC的Splitter窗口类,一个单文档接口(SDI)程序可以针对同一个文档实现两个或多个视图划分框架窗口客户区。文档-视图结构可以扩展到多文档接口(MDI)程序,以支持一个文档的多视图、多个打开的文档,甚至多个文档类型。MDI程序和SDI程序的主要不同1.MDI程序从CMDIFrameWnd类继承顶层框架窗口,而不是CFrameWnd类。2.MDI程序使用基于CMDIChildWnd类的子类来表示子框架窗口。3.MDI程序使用CMultiDocTemplate而不是CSingleDocTemplate来创建文

35、档模板。4.在CMultiDocTemplate类中引用的框架窗口是子框架窗口类而不是顶层框架窗口。5.MDI程序有至少两个菜单资源,当没有文档打开时显示一个菜单,当有至少一个文档打开时显示另一个菜单。单文档框架的初始化BOOLCSinglePadApp:InitInstance()/使程序添加对OLE控件的包容支持AfxEnableControlContainer();#ifdef_AFXDLL/当使用MFC动态库时,使程序控件具有3D外观Enable3dControls();#else/当使用MFC静态库时,使程序控件具有3D外观Enable3dControlsStatic();#endi

36、f/程序用来存储配置信息的注册表值SetRegistryKey(_T(LocalAppWizard-GeneratedApplications);/加载标准的INI文件选项(包括MRU)LoadStdProfileSettings();/注册文档模板CSingleDocTemplate*pDocTemplate;pDocTemplate=newCSingleDocTemplate(IDR_MAINFRAME,/资源ID,文档的名称RUNTIME_CLASS(CSinglePadDoc),/文档RUNTIME_CLASS(CMainFrame),/主要的SDI框架窗口RUNTIME_CLASS(

37、CSinglePadView);/视图/把注册的文档模板添加到程序中AddDocTemplate(pDocTemplate);/解析命令行完成如标准Shell命令、DDE、文件打开操作CCommandLineInfocmdInfo;ParseCommandLine(cmdInfo);/处理命令行中的命令if(!ProcessShellCommand(cmdInfo)returnFALSE;/显示和更新窗口m_pMainWnd-ShowWindow(SW_SHOW);m_pMainWnd-UpdateWindow();returnTRUE;多文档框架的初始化BOOLCMultiPadApp:In

38、itInstance()AfxEnableControlContainer();/使程序添加对OLE控件的包容支持#ifdef_AFXDLLEnable3dControls();/使程序控件具有3D外观,当使用MFC动态库时。#elseEnable3dControlsStatic();/使程序控件具有3D外观,#endif/程序用来存储配置信息的注册表值SetRegistryKey(_T(LocalAppWizard-GeneratedApplications);LoadStdProfileSettings();/加载标准的INI文件选项(包括MRU)/注册文档模板CMultiDocTempl

39、ate*pDocTemplate;pDocTemplate=newCMultiDocTemplate(IDR_MULTIPTYPE,/MDI窗口的资源RUNTIME_CLASS(CMultiPadDoc),/MDI文档RUNTIME_CLASS(CChildFrame),/MDI子框架RUNTIME_CLASS(CMultiPadView);/MDI视图/把注册的文档模板添加到程序中AddDocTemplate(pDocTemplate);/创建MDI主窗口CMainFrame*pMainFrame=newCMainFrame;/加载主窗口和主资源if(!pMainFrame-LoadFram

40、e(IDR_MAINFRAME)returnFALSE;m_pMainWnd=pMainFrame;/解析命令行完成如标准Shell命令、DDE、文件打开操作CCommandLineInfocmdInfo;ParseCommandLine(cmdInfo);/处理命令行中的命令if(!ProcessShellCommand(cmdInfo)returnFALSE;/显示和更新窗口m_pMainWnd-ShowWindow(SW_SHOW);m_pMainWnd-UpdateWindow();returnTRUE;例子:生成一个多文档记事本视图选择为CEditView为基类不用写一行代码就实现了

41、一个记事本,可以保存,打开文档文件不用写一行代码就实现了一个记事本,可以保存,打开文档文件例子:实现多文档的MDI程序更更改改对对应应的的类类名名为为上上图图所所示示为了创建一个新的文档模板,为了创建一个新的文档模板,需要建立三个类,即需要建立三个类,即 CBallFrame(子框架窗口(子框架窗口类)、类)、CBallDoc(文档类)、(文档类)、CBallView(视图类)。(视图类)。添加添加IDR_MULTBTYPE菜单资源中菜单资源中NewHello,New Ball两个菜单项两个菜单项在在CMDIApp类中添加新增的两个菜单项的响应函数类中添加新增的两个菜单项的响应函数在在Mult

42、iBall.cpp文件中添加三个子类的头文件,插入一个新的菜单资源文件中添加三个子类的头文件,插入一个新的菜单资源IDR_BALLTYPEBOOL CMDIApp:InitInstance()/ 加加Hello模板到模板列表模板到模板列表CMultiDocTemplate* pDocTemplate;pDocTemplate = new CMultiDocTemplate(IDR_MULTIBTYPE,RUNTIME_CLASS(CHelloDoc),RUNTIME_CLASS(CHelloFrame), / custom MDI child frameRUNTIME_CLASS(CHello

43、View);AddDocTemplate(pDocTemplate);/ 加球模板到模板列表加球模板到模板列表CMultiDocTemplate* pBallTemplate = new CMultiDocTemplate(IDR_BALLTYPE,RUNTIME_CLASS(CBallDoc),RUNTIME_CLASS(CBallFrame), / custom MDI child frameRUNTIME_CLASS(CBallView);AddDocTemplate(pBallTemplate);/ create main MDI Frame windowCMainFrame* pMa

44、inFrame = new CMainFrame;if (!pMainFrame-LoadFrame(IDR_MAINFRAME)return FALSE;m_pMainWnd = pMainFrame;/ The main window has been initialized, so show and update it.pMainFrame-ShowWindow(m_nCmdShow);pMainFrame-UpdateWindow();return TRUE;添加新建文档的响应函数:添加新建文档的响应函数:OnNewHello,OnNewBall/ 下面两个菜单命令处理函数根据模板列表

45、创建一个相应的新的视图文档下面两个菜单命令处理函数根据模板列表创建一个相应的新的视图文档 void CMDIApp:OnNewHello()/ 搜索模板列表里包含搜索模板列表里包含Hello串的文档模式串的文档模式POSITION curTemplatePos = GetFirstDocTemplatePosition();while(curTemplatePos != NULL)CDocTemplate* curTemplate =GetNextDocTemplate(curTemplatePos);CString str;curTemplate-GetDocString(str, CDoc

46、Template:docName);if(str = _T(Hello)curTemplate-OpenDocumentFile(NULL);return;AfxMessageBox(No Hello Template);void CMDIApp:OnNewBall()/ 搜索模板列表里包含搜索模板列表里包含Ball串的文档模式串的文档模式 POSITION curTemplatePos = GetFirstDocTemplatePosition();while(curTemplatePos != NULL)CDocTemplate* curTemplate =GetNextDocTempla

47、te(curTemplatePos);CString str;curTemplate-GetDocString(str, CDocTemplate:docName);if(str = _T(Ball)curTemplate-OpenDocumentFile(NULL);return;AfxMessageBox(No Ball Template);修改字符串资源中修改字符串资源中IDR_MULTIBTYPE的属性值的属性值插入新的字符串资源插入新的字符串资源IDR_BALLTYPE,并设置属性值,并设置属性值将CHelloView更改继承自CEditView类:替换CHelloView类源文件与

48、头文件中所有的CView为CEditView;更改CHelloDoc类中Serialize序列化函数的实现为:(CEditView*)m_viewList.GetHead()-SerializeRaw(ar);这样就可以实现将CHelloView由普通的视图类调整为可以编辑保存的编辑视图对象;在CBallView的OnDraw()函数中添加代码如下:CRectrect;GetClientRect(rect);pDC-SetTextAlign(TA_BASELINE|TA_CENTER);/设置文本排列居中pDC-SetTextColor(RGB(255,0,0);/设置文本颜色pDC-SetB

49、kMode(TRANSPARENT);/设置背景模式为透明pDC-TextOut(rect.Width()/2,rect.Height()/2,BallView,9);例子二单文档多视图(分割视图)1.首先创建一个MFC单文档应用程序。2.添加4个MFC类TopLView、BottomLView、TopRView、BottomRView,基类为CView。3.添加一个MFC类CControlForm,基类为CFormView,对话框ID默认。4.创建一个切分类,如MySplitter,基类为CSplitterWnd(默认基类选项中无此类,可以先选择CFrameWnd类,生成后再修改为CSpli

50、tterWnd类)。5.在框架类Cmainframe的头文件中,添加2个MySplitter的变量(因为下面要进行两次切分操作m_wndSplitter,m_wndSplitter2)。6.重写框架类CMainframe的OnCreateClient函数,如下:/第一次静态切分CreateStatic,一行两列if(!m_wndSplitter.CreateStatic(this,1,2)returnFALSE;/第二次静态切分(将第一次切分后的第二列再分为2*2)及所有的子视图创建(CreateView函数)。if(!m_wndSplitter.CreateView(0,0,RUNTIME_

51、CLASS(CControlForm),CSize(100,100),pContext)|!m_wndSplitter2.CreateStatic(&m_wndSplitter,2,2,WS_CHILD|WS_VISIBLE,m_wndSplitter.IdFromRowCol(0,1)|!m_wndSplitter2.CreateView(0,0,RUNTIME_CLASS(CTopLView),CSize(350,240),pContext)|!m_wndSplitter2.CreateView(1,0,RUNTIME_CLASS(CBottomLView),CSize(350,240),

52、pContext)|!m_wndSplitter2.CreateView(0,1,RUNTIME_CLASS(CTopRView),CSize(350,240),pContext)|!m_wndSplitter2.CreateView(1,1,RUNTIME_CLASS(CBottomRView),CSize(350,240),pContext)m_wndSplitter.DestroyWindow();returnFALSE;/returnCFrameWnd:OnCreateClient(lpcs,pContext);/注释掉原有的响应函数注意:记得在Mainfrm.h中添加以上五个视图类的

53、头文件:#includeControlForm.h#includeTopLView.h#includeTopRView.h#includeBottomLView.h#includeBottomRView.h#include“MySplitter.h”将CMySplitter的构造函数与析构函数改为public属性第四章:简单绘图绘制线条要求:单击鼠标左键并按住拖动后,释放鼠标左键,完成线条的绘图。1.新建单文档类型程序,名为Draw,添加鼠标左键按下及释放的消息响应函数;2.为CDrawView类添加Cpoint类型成员变量m_ptOrigin;使用SDK全局函数绘制线条:GetDc可以在任意

54、位置绘图,前提是得到任意绘图区域的句柄可以在任意位置绘图,前提是得到任意绘图区域的句柄必须记住释放资源必须记住释放资源利用MFC的CDC类绘图默认获得的是当前上下文环境下的设备句柄,默认获得的是当前上下文环境下的设备句柄,此处获得的是此处获得的是CDrawView对象的指针句柄对象的指针句柄利用MFC的CClientDC类绘图CClientDC类的构造函数会调用类的构造函数会调用GetDC,析,析构函数会调用构函数会调用ReleaseDC,因此不需要显式,因此不需要显式的释放资源;的释放资源;当将当将this更改为更改为GetParent()函数时,则可以函数时,则可以在窗口的整个区域绘图包括

55、菜单栏、工具栏,在窗口的整个区域绘图包括菜单栏、工具栏,非客户区域;因为非客户区域;因为CDrawView是由是由CMainFrame对象生成的,因此此处获得的对象生成的,因此此处获得的即为整个程序的框架窗口设备句柄;即为整个程序的框架窗口设备句柄;利用MFC的CWindowDC类绘图获得了桌面窗口的句柄,故可以实现在整个获得了桌面窗口的句柄,故可以实现在整个桌面绘图;桌面绘图;第五章:菜单操作GetMenu获得菜单项,获得菜单项,GetSubMenu获得菜单项的子获得菜单项的子菜单,菜单,checkMenuItem设置设置/删除菜单项的复选标志删除菜单项的复选标志设置默认菜单项,将会以粗体方

56、式显示加载图标菜单项获得默认的菜单项所能加载的位图的尺寸,并已消息获得默认的菜单项所能加载的位图的尺寸,并已消息框方式显示出来,此处为框方式显示出来,此处为13*13在位图资源编辑器中编辑位图,使之大小为在位图资源编辑器中编辑位图,使之大小为13*13,也可以采用其他工具调整位图大小;,也可以采用其他工具调整位图大小;移除和加载菜单项Cmenu为局部对象,可能导致异常,要么将为局部对象,可能导致异常,要么将menu对象更改为对象更改为CMainFrame的成员变量,的成员变量,要么增加一条语句:要么增加一条语句:menu.Detach();创建快捷菜单(右键菜单)1.在资源选项的Menu文件夹

57、下右键单击,选择InsertMenu命名为IDR_POPUP_MENU在里面填一些菜单项;2.选中视图类,在属性中选择消息:WM_CONTEXTMENU,添加函数函数;voidCMyDrawView:OnContextMenu(CWnd*pWnd,CPointpoint)/TODO:在此处添加消息处理程序代码CMenum_menu;m_menu.LoadMenuW(IDR_POPUP_MENU);CMenu*popupmenu=m_menu.GetSubMenu(0);popupmenu-TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,

58、point.y,pWnd,0);第六章对话框对话框的作用:主要功能是用于接收用户的输入数据;还可用来显示提示信息(如程序启动时显示版权和运行进度信息)。在MFC中,对话框的功能被封装在CDialog类中,而CDialog类是CWnd类的派生类。作为窗口,对话框和其它窗口一样具有窗口的一切功能。对话框的典型应用:通过菜单命令或工具栏按钮打开一个对话框;对话框也可以作为一个程序的主界面。对话框对话框: 是Windows应用程序中一种常用的资源,其主要功能是输出信息和接收用户的输入数据。控件控件: 是嵌入在对话框中或其它父窗口中的一个特殊的小窗口,它用于完成不同的输入、输出功能。基于对话框的应用程序

59、可以直接利用MFCAppWizard向导创建一个基于对话框的应用程序,这种程序运行后首先出现一个对话框。在向导的第一步选择DialogBased项。因为对话框应用程序一般不包含文档,故不支持数据库和复合文档。按照对话框应用程序向导提示的步骤进行操作就得到一个对话框应用程序项目,出现对话框编辑器和控件工具栏浮动窗口,它们采用的是一种所见即所得的可视化工作方式。利用向导创建应用程序的框架后,程序员可根据程序具体功能要求添加代码。当一个有模式对话框打开时,用户只能与该对话框进行交互,而其他用户界面对象收不到输入信息。平时所遇到的大部分对话框都是有模式对话框。无模式对话框则不然,该对话框并不阻止用户的

60、输入。对话框的初始化OnInitDialog():该函数是由消息WM_INITDIALOG来激活的,但此消息比较特别,它不用添加到消息映射表中。该函数用来进行对话框的初始化,为使用对话框进行准备工作。该函数的原型为:virtualvoidOnInitDialog();而且CDialog类中提供了它的默认实现,即在CDialog的派生类中将根据需要决定是否重写该函数。对话框的结束在CDialog类中存在两个关键函数OnOK()和OnCancel(),这两个函数用于响应单击OK按钮(控件ID为IDOK)和Cancel按钮(控件ID为IDCANCEL)的消息,这些消息也不用添加到消息映射表里。两个函

61、数都用于关闭对话框并返回对话框拥有者的窗口,但返回结果不同。OnOK()函数返回IDOK,并把对话框输入的数据结果提供给对话框的拥有者,而OnCancel()函数返回IDCANCEL,但并不把对话框输入的数据结果提供给对话框的拥有者。有关对话框的常用处理函数CDialog:CDialog()通过调用派生类构造函数,根据对话框资源模板定义一个对话框。CDialog:DoModal()激活模态对话框,显示对话框窗口。CDialog:Create()根据对话框资源模板创建非模态对话框窗口。如果对话框不是Visible属性,还需通过调用CWnd:ShowWindow()函数显示非模态对话框窗口。CDi

62、alog:OnOk()单击OK按钮时调用该函数,接收对话框输入数据,关闭对话框。CDialog:OnCancel()单击Cancel按钮或按Esc键时调用该函数,不接收对话框输入数据,关闭对话框。CDialog:OnInitDialog()WM_INITDIALOG消息处理函数,在调用DoModal或Create函数时系统发送WM_INITDIALOG消息,在显示对话框前调用该函数进行初始化。CDialog:EndDialog()用于关闭模态对话框窗口。CWnd:ShowWindow()显示或隐藏对话框窗口CWnd:DestroyWindow()关闭并销毁非模态对话框CWnd:UpdateDa

63、ta()通过调用DoDataExchange()设置或获取对话框控件的数据CWnd:DoDataExchange()被UpdateData()调用以实现对话框数据交换,不能直接调用不能直接调用。CWnd:GetWindowText()获取对话框窗口的标题CWnd:SetWindowText()修改对话框窗口的标题CWnd:GetDlgItemText()获取对话框中控件的文本内容CWnd:SetDlgItemText()设置对话框中控件的文本内容CWnd:GetDlgItem()获取控件或子窗口的指针CWnd:MoveWindow()用于移动对话框窗口CWnd:EnableWindow()使窗

64、口处于禁用或可用状态对话框数据交换DDX和验证DDV在对话框中实现用户数据输入和输出的一般方法是通过ClassWizard类向导将对话框控件与成员变量相关联,利用对话框数据交换DDX(DialogDataExchange)和验证DDV(DialogDataValidation)机制实现数据的输入和输出。 DDXDDX是将成员变量与对话框控件相连接,完成数据在成员变量与控件之间的交换。 DDVDDV用于数据的校验,它能自动校验输入的数据是否符合设计要求。对话框数据交换与验证都是通过DoDataExchange()完成。当利用ClassWizard类向导添加成员变量时,用户如果在窗口的左下角输入数

65、据的范围,ClassWizard将自动加入函数DDV的调用代码。例如,当添加一个UINT型的成员变量m_nInput时指定它的最小值 和 最 大 值 分 别 为 0和 100, 则 ClassWizard类 向 导 将 在 成 员 函 数 DoDataExchange()中添加以下DDV函数的调用语句:DDV_MinMaxUInt(pDX,m_nInput,0,100);程序运行后,如果用户的输入数据超出0100的范围,DDV将显示一个提示信息对话框,提示用户有效的输入范围。UpdateData()的用法当调用UpdateData(TRUE)时,MFC通过调用DDX函数将数据从控件传递到关联的

66、成员变量;当调用UpdateData(FALSE)时,MFC通过调用DDX函数将数据从成员变量传递到关联的的控件。利用UpdateData()函数实现了在刷新后重新获取成员变量。对话框中的对话框中的成员变量成员变量UpdateData(TRUE)UpdateData(FALSE)初始化成员初始化成员变量变量更新后重新获更新后重新获取成员变量取成员变量注意当程序调用CDialog:DoModal()创建并显示对话框时,将自动调用CDialog:OnInitDialog()完成初始化的工作。在函数OnInitDialog()中,程序会自动调用UpdateData(FALSE),将数据从成员变量传递

67、到关联的控件,从而显示在控件中。单击OK按钮将调用CDialog:OnOk()函数,在OnOK()中程序会自动调用UpdateData(TRUE),将数据从控件传递到关联的成员变量。DDX就如同一条双向通道,而方向控制开关就是UpdateData()函数中的BOOL类型参数是TRUE还是FALSE。提示信息对话框提示信息对话框也称消息对话框,用来显示有关的提示信息。提示信息对话框是一种最简单的对话框,不需要用户自己创建它就可以直接使用,VisualC+提供了相应的函数实现这样的功能。MFC全局函数:intAfxMessageBox(LPCTSTRlpText,UINTnType=MB_OK,U

68、INTnlDHelp=0);API函数:intMessageBox(HWNDhWnd,LPCTSTRlpText,LPCTSTRlpCaption,UINTnType);CWnd类的成员函数:intCWnd:MessageBox(LPCTSTRlpText,LPCTSTRlpCaption=NULL,UINTnType=MB_OK); 注意:它们的功能基本相同,但适用范围有所不同:AfxMessageBox()和MessageBox()可以在程序中任何地方使用,而CWnd:MessageBox()只能用于控件、对话框、窗口等一些窗口类中。AfxMessageBox(参数保存到文件失败!, MB

69、_ICONINFORMATION|MB_OK);MessageBox(NULL, The key you pressed is A or a ! , KEYDOWN, MB_ICONINFORMATION|MB_OKCANCEL); MessageBox(NULL, The key you pressed is not b or B !,KEYDOWN,NULL);MessageBox(下传独立参数完成!);例如,在软件安装过程中为了弹出如下图所示的例如,在软件安装过程中为了弹出如下图所示的警警告提示信息对话框告提示信息对话框并进行相应的处理:并进行相应的处理:编写的代码如下:intnChoi

70、ce=MessageBox(文件复制失败!,错误,MB_ICONWARNING|MB_ABORTRETRYIGNORE);switch(nChoice)case IDABORT: /用户按下终止按钮./处理功能caseIDRETRY: /用户按下重试按钮./处理功能case IDIGNORE:/用户按下忽略按钮./处理功能使用对话框为了在屏幕上显示对话框:(1)首先需要建立对话框资源及其与资源相关的对话框类;(2)然后添加控件、与控件关联的成员变量和消息处理函数;(3)最后在程序中显示对话框并访问与控件关联的成员变量。在VisualC+中可以利用集成工具如对话框编辑器和ClassWizard类

71、向导很方便地创建对话框,不需要程序员手工编写太多的源代码。模态对话框与非模态对话框模态对话框:在关闭之前,用户将无法在同一个应用程序(准确地说,是在同一用户接口线程里)的其他地方进行工作。比如,OpenFile对话框。非模态对话框:在它仍保留在屏幕上的同时,用户还可以在应用程序的其他窗口进行工作。常用的Find查找和Replace替换对话框就是非模态对话框。如果关闭非模态对话框的父窗口,非模态对话框一般也自动关闭。模态对话框工作流程定义对话框类;利用对话框类声明一个对话框对象,即一个能够在屏幕上显示的对话框;通过对话框对象调用对话框类的成员函数DoModal()建立对话框 窗 口 并 显 示

72、对 话 框 。 例 如 , 假 设 定 义 了 一 个 名 为CMyDialog的对话框类,为了在屏幕上显示一个对话框,可以编写如下代码:CMyDialogmyDlg;myDlg.DoModal();OnOK()OnOK()、OnCancel()OnCancel()与与DoModal()DoModal()的关系:的关系:对 话 框 中 一 般 都 有 OK和 Cancel按 钮 , 单 击 OK按 钮 时 调 用 CDialog:OnOK()函数,单击Cancel按钮时调用CDialog:OnCancel()函数。OnOK()函数和OnCancal()函数都将结束DoModal()函数调用,但

73、令DoModal()返回不同的值,用户可以根据DoModal()的返回值做出不同的选择。OnOK()函数令DoModal()返回IDOK;OnCancel()函数令DoModal()返回IDCANCAL。例如:if(myDlg.DoModal()=IDOK)对话框的初始化可以在三个不同阶段所调用的函数中进行:(1)对话框类构造函数;(2)WM_CREATE消息处理函数;(3)WM_INITDIALOG消息处理函数。注意:对话框的初始化通常是在消息WM_INITDIALOG的消息处理函数OnInitDialog()中进行。在收到WM_INIT-DIALOG消息时,对话框的框架已创建,对话框中的每

74、个控件也已建立起来,但它们还没有在屏幕上显示。此时自然可以设置或优化对话框中各个控件的外观、尺寸、位置以及其它属性。函数OnInitDialog()将被成员函数DoModal()调用。创建一般的模态对话框的基本步骤用对话框编辑器创建包含各种控件的对话框资源,指定对话框本身的属性(如大小、位置、风格、类型等)和对话框中的控件及属性。对话框编辑器会对工程的资源文件进行更新,使之包含新的对话框资源,并且该工程的resource.h也会被更新。用ClassWizard创建CDialog类的派生类,并将它与第一步创建的资源文件相连接。ClassWizard会自动在工程中加入相应的代码和头文件。利用Cla

75、ssWizard向对话框类添加数据成员、交换函数和确认函数。利用ClassWizard对对话框中的按钮好其他可以产生事件的控件加入相应的消息处理函数。对一些特殊的控件初始化函数以及消息控制函数进行编辑。对视图代码进行编辑,以激活对话框。在程序中使用创建的模态对话框例通过对话框输入一个圆的半径,根据输入值在屏幕上画圆。v方案1:建一个SDI类型的项目,利用菜单打开一个对话框,获得输入的半径后在视图里重画。(见课本例子)v方案2:直接用对话框输入数据和显示图形添加控件结合对话框编辑器,利用Controls控件工具栏可给当前正在编辑的对话框模板资源添加控件。若VisualC+窗口中没有出现Contr

76、ols工具栏,只需将光标指向菜单栏并单击鼠标右键,从弹出式菜单中选择Controls项。控件工具栏上的每一个图标都代表了一种控件,如果不能确定控件的类型,只要将光标在该控件图标上停留片刻,就会显示该控件类型的提示。 向对话框添加控件时,先在向对话框添加控件时,先在Controls工具栏工具栏单击要添单击要添加的控件,再将光标指向对话框空白区域并单击鼠标。加的控件,再将光标指向对话框空白区域并单击鼠标。添加与控件关联的成员变量在生成自己的对话框类并添加需要的控件后,可以利用ClassWizard类向导在对话框类的定义中为对话框资源上的每一个控件添加一个或多个对应的成员变量。ClassWizard

77、类向导的MemberVariables页面主要用来为对话框类添加和删除与对话框控件关联的成员变量,我们在编写对话框程序时经常同该页面打交道。MemberVariables页面:Class name下 拉 框 : 选 择 要 添 加 成 员 变 量 的 对 话 框类;AddVariable按钮:添加与控件关联的成员变量;DeleteVariable按钮:删除控件的某个成员变量。Control IDs栏:列出对话框资源上已有的控件,第1列ControlIDs表示控件的ID,第2列Type表示变量的类型,第3列Member表示成员变量名。AddMemberVariable对话框输入成员输入成员输入成

78、员输入成员变量名变量名变量名变量名选择成员变选择成员变选择成员变选择成员变量的类型量的类型量的类型量的类型选择成员变量的类选择成员变量的类选择成员变量的类选择成员变量的类别,可为别,可为别,可为别,可为: : : :ControlControlControlControl或或或或ValueValueValueValueCategory下拉框选择Value项:表示要为该控件的某项属性定义一个变量,这意味着程序关心的是控件中的值,而不是控件对象本身。可以通过Variabletype下拉框为变量选择不同的类型。选择Control项:表示定义的变量代表控件对象本身,Control类别的变量实质是一个控

79、件对象,其类型是MFC控件类。可以通过添加的控件对象访问控件类的成员变量和调用控件类的成员函数,实现对控件行为的控制和管理。可以为一个控件同时定义一个Control类别的变量和一个Value类别的变量。这些变量都是作为对话框派生类的成员变量,为了在程序其它地方能够直接访问添加的成员变量,它们都被声明为public属性。非模态对话框的创建对于非模态对话框,使用对话框编辑器创建对话框资源和使用ClassWizard类向导添加对话框类、成员变量和消息处理函数的方法与模态对话框一样,但创建和退出对话框的方式有所不同。创建模态对话框时是由系统自动分配内存空间,因此在退出对话框时,系统自动调用CDialo

80、g:EndDialog()函数来删除对话框。而创建非模态对话框则需要用户来分配内存,退出时还需用户自己删除非模态对话框。非模态对话框的实例应声明为全局对象,不能象模态对话框那样作为局部对象。一般用new操作符生成,使用结束时用delete操作符将其删除。区别于模态对话框,非模态对话框用new生成对象后,不是调用CDialog:DoModal()函数,而是调用CDialog:Create()函数装入对话框资源,并创建和显示对话框。Create()函数在显示非模态对话框后就立即返回,而DoModal()函数是在模态对话框被关闭之后才返回。并且,由于Create()函数不会启动新的消息循环,非模态对

81、话框与应用程序共用一个消息循环,这样,非模态对话框就不会垄断用户的输入。非模态对话框创建的基本步骤利用对话框编辑器创建对话框资源,并向对话框中加入所需控件。用Class Wizard创建非模态对话框类。给新创建的对话框加入成员变量。定义非模态对话框的构造函数和对话框窗口的创建函数。定义要传送的消息。非模态对话框对象的创建和删除。公用对话框Windows将一些常用的对话框集成到操作系统中,作为Windows公用对话框库Commdlg.dll的一部分。用户在程序中可以直接使用这些公用对话框,不必再创建对话框资源和对话框类,并且,用户还可以定制公用对话框的外观和性能。为了在MFC应用程序中使用公用对

82、话框,MFC提供了封装这 些 公 用 对 话 框 的 类 。 这 些 公 用 对 话 框 类 都 是 从CCommonDialog类派生而来,而CCommonDialog类又是CDialog类的派生类。公用对话框公用对话框 MFC公用对话框类公用对话框类CColorDialogCFileDialog CFindReplaceDialogCFontDialogCPagesSetupDialogCPrintDialogCOleDialog说说 明明颜色设定对话框,选择不同的颜色颜色设定对话框,选择不同的颜色文件存取对话框,打开或保存文件文件存取对话框,打开或保存文件查找和替换对话框,查找和替换文本

83、串查找和替换对话框,查找和替换文本串字体设定对话框,选择不同的字体。字体设定对话框,选择不同的字体。页面设置对话框,设置页码、页眉等页面设置对话框,设置页码、页眉等标准的打印对话框,用于打印和打印设置标准的打印对话框,用于打印和打印设置该类及其派生类用于生成该类及其派生类用于生成OLE对话框对话框例子:有提示信息的对话框在派生的对话框类中创建一个提示信息控件(CToolTipDlg),利用GetWindow()函数获得对话框里所有控件的窗口指针,以及利用LoadString()函数获得提示信息字符串,然后把对应的窗口指针和提示信息添加到CToolTipDlg控件中。在消息的预处理函数PreTr

84、anslateMessage()中调用CToolTipDlg:RelayEvent()函数,用于将鼠标的消息发送给CToolTipDlg控件,由CToolTipDlg控件处理是否显示相应的提示信息。利用MFCAppWizard(exe)创建一个新工程DlgExample,在向导的第(1)步选择对话框模式,而后使用默认值来创建,最后获得一个对话框的应用程序,在对话框中添加一些控件。在ClassView中添加新的类CToolTipDlg,类的类型为MFCClass,基类为CDialog。得到两个新文件ToolTipDlg.cpp和ToolTipDlg.h。在CToolTipDlg类中将自动生成的构

85、造函数CToolTipDlg(CWnd*pParent=NULL)改为CToolTipDlg(UINTuID,CWnd*pParent=NULL)。在CToolTipDlg类中利用ClassWizard添加要重写的虚函数PreTranslateMessage()。在CToolTipDlg类中利用ClassWizard添加消息WM_INITDIALOG。在消息处理函数OnInitDialog()中添加以下代码:BOOLCToolTipDlg:OnInitDialog()CDialog:OnInitDialog();/创建提示信息控件m_wndToolTip.Create(this);m_wndT

86、oolTip.Activate(TRUE);/获得对话框的第一个控件(子窗口)指针CWnd*pWndChild=GetWindow(GW_CHILD);CStringstrToolTip;/循环获得所有控件指针,并将这些控件的提示信息加入到提示信息控件while(pWndChild)intnID=pWndChild-GetDlgCtrlID();/获得控件ID对应的提示信息字符串if(strToolTip.LoadString(nID)/将控件对应的提示信息注册到提示信息控件里m_wndToolTip.AddTool(pWndChild,strToolTip);/获得对话框的下一个控件(子窗口

87、)指针pWndChild=pWndChild-GetWindow(GW_HWNDNEXT);returnTRUE;重写虚函数PreTranslateMessage(),将所有鼠标消息发送给CToolTipCtrl控件,源代码如下:BOOLCToolTipDlg:PreTranslateMessage(MSG*pMsg)/WM_MOUSEFIRST为第一个鼠标消息值/WM_MOUSELAST为最后一个鼠标消息值if(pMsg-message=WM_MOUSEFIRST&pMsg-message=WM_MOUSELAST)MSGmsg;:CopyMemory(&msg,pMsg,sizeof(MS

88、G);/获得消息结构里窗口句柄的父窗口句柄HWNDhWndParent=:GetParent(msg.hwnd);/判断父窗口句柄是否是对话框句柄/若不是则一直往上找/保证消息结构中窗口句柄是对话框的控件句柄while(hWndParent&hWndParent!=m_hWnd)msg.hwnd=hWndParent;hWndParent=:GetParent(hWndParent);/若是对话框控件的消息,将鼠标消息发送给CToolTipCtrl控件/然后由控件来处理这些消息,判断是否显示提示信息if(msg.hwnd)m_wndToolTip.RelayEvent(&msg);return

89、CDialog:PreTranslateMessage(pMsg);将前面添加对话框的对应类CDlgExampleDlg从CToolTipDlg中继承,在ResourceView的StringTable中添加控件ID相对应的提示信息。编译、运行该应用程序,当鼠标停留在控件上时就会显示提示信息。第七章定制应用程序外观自定义窗口大小自定义窗口标题自定义窗口标题定制窗口的图标,光标和背景黑色画刷作为窗口背景黑色画刷作为窗口背景自定义光标自定义光标自定义图标自定义图标窗口背景仍然是白色,光标仍窗口背景仍然是白色,光标仍然是默认的光标,为何?然是默认的光标,为何?答:因为应用程序默认有两个窗口,一个是框

90、架窗口,一个是视图窗口,视图窗口覆盖在答:因为应用程序默认有两个窗口,一个是框架窗口,一个是视图窗口,视图窗口覆盖在框架窗口之上,我们只改变了框架窗口的背景和光标,但是被视图窗口给挡住了。因此应框架窗口之上,我们只改变了框架窗口的背景和光标,但是被视图窗口给挡住了。因此应该在视图类的创建窗口之前,改变设置该在视图类的创建窗口之前,改变设置如何动态显示应用程序的图标预先准备好几幅图标资源,然后再程序中每隔一定的时间按顺序循环显示这几幅图标,从而就实现了一种动画的效果。编码时只要利用定时器和SetClassLong函数就可以完成这个功能。SetClassLong函数允许窗口在创建完成之后修改窗口的

91、外观属性。因此只要每隔一定的时间调用一次这个函数即可。1.准备好三幅图标,可以在网站下载;2.将资源编辑器中导入这三个图标,并定义其唯一的ID号,IDI_ICON1,IDI_ICON2,IDI_ICON33.在CMainFrame类中,定义一个图标句柄数组成员变量,用来存放这三幅图标的句柄,如:Private:HICONm_hIcons3;4.在CMainFrame类的OnCreate函数中利用LoadIcon函数加载三个图标:三种获得应用程序句柄的方法三种获得应用程序句柄的方法MAKEINTRESOURCE()宏将宏将资源资源ID号转换为资源表示字符号转换为资源表示字符串串在CMainFra

92、me类中添加定时器响应函数启动的时候就显示自定义的图标进入夏天,少不了一个热字当头,电扇空调陆续登场,每逢此时,总会想起进入夏天,少不了一个热字当头,电扇空调陆续登场,每逢此时,总会想起那一把蒲扇。蒲扇,是记忆中的农村,夏季经常用的一件物品。记忆中的故那一把蒲扇。蒲扇,是记忆中的农村,夏季经常用的一件物品。记忆中的故乡,每逢进入夏天,集市上最常见的便是蒲扇、凉席,不论男女老少,个个手持乡,每逢进入夏天,集市上最常见的便是蒲扇、凉席,不论男女老少,个个手持一把,忽闪忽闪个不停,嘴里叨叨着一把,忽闪忽闪个不停,嘴里叨叨着“怎么这么热怎么这么热”,于是三五成群,聚在大树,于是三五成群,聚在大树下,或

93、站着,或随即坐在石头上,手持那把扇子,边唠嗑边乘凉。孩子们却在周下,或站着,或随即坐在石头上,手持那把扇子,边唠嗑边乘凉。孩子们却在周围跑跑跳跳,热得满头大汗,不时听到围跑跑跳跳,热得满头大汗,不时听到“强子,别跑了,快来我给你扇扇强子,别跑了,快来我给你扇扇”。孩。孩子们才不听这一套,跑个没完,直到累气喘吁吁,这才一跑一踮地围过了,这时子们才不听这一套,跑个没完,直到累气喘吁吁,这才一跑一踮地围过了,这时母亲总是,好似生气的样子,边扇边训,母亲总是,好似生气的样子,边扇边训,“你看热的,跑什么?你看热的,跑什么?”此时这把蒲扇,此时这把蒲扇,是那么凉快,那么的温馨幸福,有母亲的味道!蒲扇是中

94、国传统工艺品,在是那么凉快,那么的温馨幸福,有母亲的味道!蒲扇是中国传统工艺品,在我国已有三千年多年的历史。取材于棕榈树,制作简单,方便携带,且蒲扇的表我国已有三千年多年的历史。取材于棕榈树,制作简单,方便携带,且蒲扇的表面光滑,因而,古人常会在上面作画。古有棕扇、葵扇、蒲扇、蕉扇诸名,实即面光滑,因而,古人常会在上面作画。古有棕扇、葵扇、蒲扇、蕉扇诸名,实即今日的蒲扇,江浙称之为芭蕉扇。六七十年代,人们最常用的就是这种,似圆非今日的蒲扇,江浙称之为芭蕉扇。六七十年代,人们最常用的就是这种,似圆非圆,轻巧又便宜的蒲扇。蒲扇流传至今,我的记忆中,它跨越了半个世纪,圆,轻巧又便宜的蒲扇。蒲扇流传至今,我的记忆中,它跨越了半个世纪,也走过了我们的半个人生的轨迹,携带着特有的念想,一年年,一天天,流向长也走过了我们的半个人生的轨迹,携带着特有的念想,一年年,一天天,流向长长的时间隧道,袅长的时间隧道,袅结束

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 工作计划

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号