第九章MFC_编程简介.ppt_第1页
第九章MFC_编程简介.ppt_第2页
第九章MFC_编程简介.ppt_第3页
第九章MFC_编程简介.ppt_第4页
第九章MFC_编程简介.ppt_第5页
已阅读5页,还剩59页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、MFC 编程,主要内容,MFC简介 消息映射 文档/视图结构 走进 vc,MFC?,Windows操作系统采用了图形用户界面,借助于它提供的API(Application Programming Interface)函数,用户可以编出具有漂亮图形界面的程序。 VC+的微软基础类库(Microsoft Foundation Class Library,MFC)封装了大部分API函数,并提供了一个应用程序框架,简化和标准化了Windows程序设计。,MFC ?,MFC简介: MFC约有200个类,提供了Windows应用程序框架和创建应用程序的组件。其中只有5个核心类对应用程序框架有影响: CWi

2、nApp,CDocument,CView,CFrameWnd和CDocTemplate。 五个之中只有CWinApp是必不可少的类,CWinApp的对象在应用程序中必须有一个,也只有一个,并是一个全局对象,它建立了应用程序执行的主线程。,MFC是采用单一继承,从根类Cobject层层派生出绝大多数MFC中的类,其层次结构是最典型。参见下图,根类CObject分类派生图,MFC基础类及其层次结构,Cobject根类,CCmdTarget 命令相关类,CDC设备环境类,CClientDC、CWindowDC、CPaintDC、,CGdiObject 绘画工具类,CPen、CBrush、CFont、

3、CBitmap、CPalette、,CMenu菜单,CArray、CList、CMap、 群(集合)类,CDatabase、CRecordset、 ODBC数据库支持,CDatabase、CDataRecordset、 DAO数据库支持,CFile 文件类,CMemFile、COleStreamFile、CSocketFile、,CException 异常类,CSyncObject 同步对象类,CInternetSession 因特网会话类,CInternetConnection 因特网连接类,CFtpConnection、CGopherConnection、CHelpConnection,C

4、object派生类层次示意图,CObject根类,CCmdTarget 命令处理类,CWinThread 线程类,CDocument 文档类,CDocTemplate 文档模板类,CWnd 窗口类,CWinApp Windows应用程序类,CSingleDocTemplate 单文档模板类,CMultiDocTemplate 多文档模板类,应用程序结构,Cobject根类派生的最重要的类组成一个应用程序结构(Application Architecture)的集合,它是由CCmdTarget为基类派生出来的,其中主要部分参见图,CFrameWnd 框架窗口类,CControlBar 控制条类,

5、CSplitterWnd 窗口分割类,CPropertSheet 属性表类,CMDIFrameWnd、CMDIChildWnd、CMiniFrameWnd,CDialogBar、CToolBar、CStatusBar,CWnd 窗口类,CDialog 对话框类,CCommonDialog 公用对话框类,CProperty 属性页表,CFileDialog、CColorDialog、,应用程序结构,CView 视图类,控制类 CButton、CEdit、CListBox、CScrollBar、CStatic、CComboBox,CCtrlView,CFormView,CEditView、CLis

6、tView、CTreeView、CRichEditView,CRecordView,应用程序结构,基类Cobject的最基本功能: 1. 支持序列化(serialization)。序列化指如何让一个对象保持持久不变,即把对象成员数据内容存入一个文件或从一个文件中读取内容重构对象的过程。 2. 运行时(Run-time)类的信息获取。 3. 提供特定的new,delete和=操作符,完成对象的建立与删除。,MFC的消息映射,消息映射的概念: MFC由CWinApp类检索和派送消息给相应的窗口函数,但是所有的MFC窗口函数都使用同一个窗口函数。 MFC把设计窗口的任务细化为设计若干消息处理函数,程

7、序员要做的是为每一个要处理的消息提供一个消息处理(Handling Messages)函数,然后系统通过MFC提供的一套消息映射系统(messages mapping system)来调用相应的消息处理函数。消息映射就是消息与消息处理函数一对一的联系。,消息映射机制,Windows的消息主要有三种类型: 窗口消息 控制的通知消息 命令消息,MFC的消息映射,窗口消息:(WM_CREATE,WM_DESTROY,WM_CLOSE)由MFC的窗口类(CWnd)对象来处理,即这类消息处理函数一般是CWnd类的成员函数。有缺省窗口处理函数 若CWnd派生类没有重载上述两类消息处理函数,则消息映射机制会

8、转由其基类处理(最终是CWnd类);若CWnd类也没有定义对应的消息处理函数,则调用Windows默认的窗口函数处理。,MFC的消息映射,控制的通知消息 控制:是一个小的子窗口,属于其他窗口(如对话框),能够接受操作并向父窗口发送消息。 常见的控制:按钮(Button)、列表框(1istBox)、编辑框(Edit)、复合框(ComboList)、滚动条(ScrollBar)等。,MFC的消息映射,命令消息处理: 来自菜单、工具栏,加速键的通知消息,参数中 包括命令标识(ID)号,它是应用程序自定义的一 些常量,由程序员编写消息处理函数。MFC也定义了一些缺省的标准命令消息处理函数。VC+有一个

9、 ClassWizard(类向导),它会帮助用户建立消息映射和消息处理函数的框架,消息和函数都由MFC缺省的命名方式命名。 对于命令消息,MFC应用程序框架会通过消息映射机制,按一定的搜索顺序在各个CCmdTarget类(命令处理类)的派生类中查找对应消息处理函数。 在编程序时应该让命令消息尽可能由与其关系密切的类来处理。也就是尽管消息处理函数可以任意安放在某一个类中,但那样可读性差,同时执行时也可能出问题。,消息映射示意图,MFC的消息映射,命令消息相应消息处理函数搜索全过程: 由菜单、工具栏等用户界面对象产生的命令消息,首先送给主框架窗口的标准MFC窗口函数,然后窗口函数把命令传给MFC主

10、框架窗口对象,进行命令消息的派送,并按下表的次序进行消息匹配。若找不到,则先继续搜索其基类的消息映射入口表,若都找不到,再迂回到下一个对象进行处理。,都找不到,则由缺省的Windows消息处理函数结束该命令消息,MFC中的文件处理,MFC中的文件系统,是广义的文件系统。先讨论MFC的文档/视结构(Document/view),再讨论序列化(Serialization)与永久保存。,1 文档/视结构,2 存档类序列化,1 文档/视结构,MFC提供了一种应用程序框架,包含三种类型的应用程序:单文档界面(SDI)应用程序、多文档界面(MDI)应用程序和基于对话框(Dialog Based)的应用程序

11、,其核心就是文档/视结构(多文档结构和单文档结构)。,普通的MFC应用程序(单文档)包含四个主要的类: 文档类 视图类 主框架窗口类 应用类,1 文档/视结构,文档与视的概念: 文档(document)指的是数据组合的抽象,它通常对应磁盘文件,也可以对应I/O端口(包括打印机、键盘)或一块内存空间(串流)。 同样的数据,我们可以用不同的方式来表示。把纯的数据放在文件中或数据库中。而把显示方式分离出来,可以让一份数据有多种不同的显示方式,程序中的数据表现称为“视” (view)。这样就可以分别考虑数据的保存文档,和数据的表现视。,1文档/视结构,文档与数据: 文档类的含义非常广泛。包括复合文档。

12、在多文档结构(MDI)中一个子窗口所掌握的数据也称为一个文档。文档就是数据,CDocument就可以简单地理解为负责处理数据的类。在MFC编程时,我们应该把所有要处理的从外部获得的数据全部放在文档类及其派生类的对象中。CDocument类是一个预先编好的类,只是提供了一个外壳或者讲框架,程序员可以在Document中建立实际要用的数据格式及其管理方法。最常用的方法当然是派生出自己的文档类(CMyDocument类)。,1 文档/视结构,视的作用: 视类(CView)负责与使用者接触。文档和视是数据的两个方面:数据的处理在文档中进行,它使用的是字节、整数、浮点数等数据,链表、顺序表和树、图等数据

13、结构。而数据的表现视使用的是绘图工具:如绘图域、画笔、调色板等等。CView是为数据的表现而设计的。 CView还负责程序与用户之间的交互。用户对数据的编辑、修改,对程序下达工作指令都要依赖窗口上的鼠标与键盘操作才能完成,这些信息由View接受后再传给Document。,1 文档/视结构,文档/视有关系统,生成一个多文档程序框架时,系统中包含着两个框架类:主框架类 CMainFrame和子框架类CChildFrame。 主框架类CMainFrame由 MFC的 CMDIFrameWnd类派生。 子框架类CChildFrame由 MFC的CMDIChildWnd派生,框架类,应用类,应用类管理程

14、序的总体,它完成不属于任何其他三类的一般工作,例如初始化程序以及进行最后的程序清除工作。每个MFC Windows程序必须正确的生成由CWinApp派生类的一个实例(对象)。,存档类序列化,存档类: 存档类(CArchive类)不是CObject的派生类,它提供运行时对象模式支持。Serialize()函数的参数是存档类CArchive对象的引用。CArchive类对象是在永久性对象(磁盘文件,CFile类对象)和非永久性对象(内存对象,如文档类对象)之间充当一个过渡角色。负责按一定的顺序和格式在两者之间进行存取。文件一般为二进制格式文件。而内存对象可以是简单数据变量,也可以是C+对象或COb

15、ject派生类对象。参见下图。,2 存档类序列化,序列化使用: MFC的存储功能被称为序列化(Serialization),CArchive对象从字面上看是档案,实际上是一个内存缓冲区,其操作速度比文件的操作要快的多。Serialize()操作的对象就是CArchive类对象。 函数CObject:Serialize是一个虚函数。实际上函数体中是空的,但Microsoft很可能改变函数体中的内容,所以Microsoft要求改写时先查看它。,存档类序列化,注意: 要使CObject派生类真正有可序列化(Serializable)的功能,必须具备下列条件: 1由CObject派生出来,以保证有运行

16、时类型识别(RTTL,Runtime Type Identification)、动态生成(Dynamic Creation)等机能。 2 改写Serialize虚函数,使它能适当地把类成员变量写入档案。 3 要加一个缺省的构造函数(无参)。MFC往往必须先动态生成存档类对象,而且是在无任何参数下生成对象。 4类声明必须包含一些必要的宏。,存档类序列化,序列化全过程: 由CWinApp:OnFileSaveAs()消息处理函数,打开一个对话框提示输入一个文件名,并创建一个该文件的CFile对象,然后把CFile对象绑定到一个CArchive对象上,最后调用文档类的Serialize()成员函数由

17、参数引用CArchive对象。 CArichive对象与内存对象之间数据流的流动方向可用成员函数IsStoring()或IsLoading()来判断当前的数据流动方向。当打开文档时,IsStoring()返回false,IsLoading()返回true。当保存文档时,返回值相反。这可避免在程序中出现按实际数据流动方向相反操作的异常。,文档序列化,使用MFC的文档/视图结构编写一个应用程序,并实现文档的序列化,该文档表示几何图形的向量。文档的视图用适当的图形来显示文档的内容。,CObject CFigure CRectangle CCircle CTriangle,走进 VC+,认识VC中的文

18、件 使用向导 添加各类资源 交互工具,h为扩展名的文件中包含的主要是类的定义,cpp为扩展名的文件中包含的主要是类成员函数的实现代码。 dsw为扩展名的文件称为Workspace文件。在VC中,应用程序是以Project的形式存在的,Project文件以.dsp扩展名,在Workspace文件中可以包含多个Project,由Workspace文件对它们进行统一的协调和管理。 opt为扩展名的文件,这个文件中包含的是在Workspace文件中要用到的本地计算机的有关配置信息。 clw为扩展名的文件是用来存放应用程序中用到的类和资源的信息的,这些信息是VC中的ClassWizard工具管理和使用类

19、的信息来源。,认识VC中的文件,认识VC中的文件,readme.txt文件,这个文件中列出了应用程序中用到的所有的文件的信息,打开并查看其中的内容就可以对应用程序的文件结构有一个基本的认识。 rc为扩展名的文件称为资源文件,其中包含了应用程序中用到的所有的windows资源,例如位图、菜单之类的资源。 rc2为扩展名的文件,它也是资源文件,但这个文件中的资源不能在VC的集成环境下直接进行编辑和修改,根据需要手工地编辑这个文件。 以ico,bmp等为扩展名的文件是具体的资源。,程序的工作步骤分析 以下是一般MFC程序运行的主要步骤: 调用CWinApp类构造函数。 程序入口函数WinMain接收

20、控制。 WinMain调用程序的InitInstance函数。 WinMain进入消息循环。 WinMain退出,程序终止。 MFC应用程序必须定义有且只有一个应用程序类的对象。,MFC程序的初始化过程的执行顺序: CWinApp:InitApplication CMyWinApp:InitInstance(初始化) CMyFrameWnd:Create CWnd:CreateEx CFrameWnd:PreCreateWindow CWinApp:Run CWinThread:Run,这个函数所完成的最主要任务如下: 定义并初始化了一个文档模板对象pDocTemplate; 完成文档模板的定

21、义后,程序又产生了一个主框架窗口,创建主框架窗口时采用的是IDR_MAINFRAME资源。 创建主框架窗口后,程序将处理命令行信息。命令行信息是跟随在命令后的参数。 最后,程序显示并更新框架窗口。,程序框架中各个类对象的相互调用关系 AppWizard产生的程序框架将文档、视图、框架(窗口)对象结合在了一起,在编制程序时,需要能够实现各个类的对象之间的联系。 (1)视图类对象对文档类对象的调用 视图的作用是在客户区显示文档的内容,两者之间的调用最为常用。在视图对象中,通过以下函数得到文档对象的指针。在类 CMyView中可以找到一个函数,此函数在 Myview.h中定义:public: CMy

22、Doc* GetDocument();/得到文档类的指针 GetDocument()在Myview.cpp中实现,,此函数的作用就是得到视图对象中属于文档对象的指针。在CMyView成员函数中可以通过以下代码得到文档对象指针: CMyDoc * pDoc GetDocument(); ASSERT_VALID(pDoc); 得到当前视图对象所对应的文档对象的指针pDoc,与使用别的类对象指针一样可以调用文档类的成员变量和成员函数(只能调用公有型的)。,(2)在框架类对象中获得当前的文档和视图对象指针 在主框架类CMainFrame和子框架类 CChildFrame中,都可以利用父类的函数得到当

23、前活动的文档类对象和视图类对象。下面的语句可以获得当前活动的文档类对象和视图类对象: CMyDoc * pDoc =(CMyDoc *) GetActiveDocument(); CMyView * pView(CMyView *) GetActiveView();,(3)获得应用类对象的指针 在MFC应用程序运行过程中,自始至终存在一个应用类对象,可以在MFC派生类中或非MFC派生类中,通过全局API函数AfxGetApp得到应用类对象的指针。如可以在Draw系统中的任何地方,通过以下代码获得程序应用类对象的指针: CMyApp *pWinApp=(CMyApp *)AfxGetApp ()

24、;,(4)从应用类对象中获得主框架类对象的指针 通过MFC应用程序运行时的应用类对象,可以获得当前应用程序的主框架类对象的指针。在应用类CWinApp中存在个数据成员m_pMainWnd,其中包含指向应用程序主框架类的指针。通过此指针可以获得当前应用程序中主框架类对象的指针.以下操作可实现获得主框架对象的指针: CMainFrame *pFrame=(CMainFrame*)(AfxGetApp()-m_pMainWnd); 此代码可以应用在视图类、文档类,以及非MFC派生类的成员函数(如全局函数)中,通过API函数获得的应用类对象指针(AfxGetApp()得到主框架类的指针。,通过AfxG

25、etApp()函数获得应用类对象的指针,再通过应用类对象得到主框架类对象的指针,通过主框架窗口对象又可以获得当前活动的文档和视图对象的指针,这种调用可以保证在各种情况下获得MFC应用程序中各主要类对象的指针,通过指针使用各类对象的成员(数据或函数)。,V C+ 编程环境下的开发工具,AppWizard ClassWizard ClassView FileView ResourceView,VC+提供了两个主要的代码生成器(或称为向导),主要功能是用来生成应用程序的初始化与事件循环代码框架。 1、AppWizard AppWizard是用来建立程序框架的。 VC+功能强大,可以开发多种不同的应用

26、程序,如 MFC的 Windows应用程序(.exe),基于Windows的动态链接库(.dll)等,不同类型的应用程序具有不同的应用程序框架。对于每一类应用程序,不需从零进行开发,通过AppWizard就可以自动生成包含一些基本功能的应用程序框架,开发者可以在此基础上进行程序设计。 AppWizard生成的应用程序框架在应用程序和Win32 API之间搭建了接口,并将API库函数封装到一些类中。,ClassView ClassView是VC+工作平台上的一个工具,它通过对应用 程序的包含文件(.h)和实现文件(.cpp)进行处理,从中得到应用 程序中所包含的类的信息。可以实现增加类、增加类的

27、成员函 数和成员数据,以及在包含文件和实现文件中定位各个类、类 的成员函数及成员变量等各种操作。 对于大的应用程序系统,使用ClassView工具,使成员函 数、变量的定位和增加类、类的成员的工作变得容易。 其主要功能:,编辑定位 利用ClassView的定位功能迅速找到需要进行编辑的源文件的位置。 增加类 增加的类分两种: (1)MFC的继承类,从VC+中已有的MFC类继承而来; (2)一般的C+类。 要选择基类,确定类的存放位置(名称)。 增加类的成员 使用ClassView可增加的成员:成员变量、成员函数、可重载的虚函数等。,(2) ResourceView ResourceView是V

28、C+中对程序的资源进行可视化管理的工具,利用它调用AppStudio可以对程序所拥有的各种资源(如菜单、工具条、对话框、加速键、热键等)进行可视化管理。 ResourceView的工作基础是资源文件(.rc)、资源ID号定义文件(Resource.h)和一些用到的实际资源(位图、图标等)。,ResourceView工作过程分析 ResourceView及其工具类似一个翻译器,将资源文件中文本描述的资源翻译成可视化的资源形态,并在可视化状态下修改,修改完成后,再把资源写入资源文件中。其工作过程: 读入资源、编辑资源、保存资源 (3) FileView FileView是VC+工作平台上管理一个开

29、发项目所包含的各种文件的工具,通过它可以管理一个开发项目所包含的文件。,2、使用ClassWizard ClassWizard是VC+中一个功能强大的辅助编程工具,它通过对包含文件(.h)和实现文件(.cpp)进行工作,能够对类中的消息处理函数、可重载的虚函数、映射数据、ActiveX事件等进行管理和辅助编程。 Windows应用程序是通过消息来控制流程的, AppWizard生成的应用程序为消息设计程序提供了很好的框。C1assWizard为管理消息处理函数等提供了一个强大的工具。 C1assWizard允许程序员将特定类型的事件映射到某个函数上去, C1assWizard为该函数推荐一个以

30、On为前缀的函数名,并提供适当的参数和返回值。,ClassWizard 的作用 ClassWizard 是一个好的辅助设计工具,可以完成对消息处理函数,继承类的可重载虚函数,映射变量,自动化变量以及ActiveX事件的管理工作。 ClassWizard 管理消息处理函数 1.窗口消息处理函数 ClassWizard识别和处理窗口消息处理函数所需要的标识 。 ClassWizard是通过固定的标识来识别窗口消息处理函数的: 在包含文件中 /AFX_MSG(消息处理函数所在类的名称) /AFX_MSG 只有将消息处理函数写在以上两行代码内才能被ClassWizard识别和处理。,在实现文件中 消息

31、处理函数的映射机制(映射宏)写在 /AFX_MSG_MAP(消息处理函数所在类的名称) /AFX_MSG_MAP 内而被ClassWizard识别。 删除消息处理函数 ClassWizard删除标识内的部分,函数实现代码需手工删除。 总结: 一个类只有在包含文件和实现文件中的识别符正确存在时,ClassWizard才能对这个类的窗口消息处理函数进行管理。只有这个类的窗口消息处理函数的声明和映射机制都写在识别符以内,ClassWizard才能识别和处理这个消息处理函数。,ClassWizard管理可重载的虚函数 VC+产生的框架程序中有很多标准操作功能,由一系列函数组成,其中应用了很多可重载的虚

32、函数。ClassWizard可以用来管理这些被重载的虚函数。 ClassWizard 识别和处理重载的虚函数所需要的标识 ClassWizard能够识别定义在以下标识语句内的虚函数: /AFX_VIRTUAL(重载虚函数的类的名称) /虚函数的定义位置 /AFX_VIRTUAL ClassWizard管理映射变量 1、映射变量,映射变量是这样一个变量, 一方面它是一个普通变量;另一方面,它通过一定的机制与某个控制建立联系,用它既可以表示某个控制的内容和状态,也可以用它的初值初始化控制的内容和状态。 2、用ClassWizard可以增加和删除映射变量 3、ClassWizard识别和处理映射变量

33、所需要的标识 变量定义 /AFX_DATA(变量属于的类名称) /AFX_DATA 变量的初始化 /AFX_DATA_INIT(变量属于的类名称) /AFX_DATA_INIT 变量与控制的交换代码 /AFX_DATA_MAP(变量属于的类名称) /AFX_DATA_MAP,总结 映射变量可以完成变量与控制之间的数据交换,可用来方便的组织对话框的控制界面。,MFC对消息的处理,MFC不使用C语言编写Windows程序时用的易产生错误的switch/case语句,而是采用一种消息映射机制来决定如何处理特定的消息。这种消息映射机制包括一组宏,用于标识消息处理函数、映射类成员函数和对应的消息等。其中

34、,用afx_msg放在函数返回类型前面,用以标记它是一个消息处理成员函数。类若至少包含了一个消息处理函数,那么还需要加上一个DECLARE_MESSAGE_MAP( )宏,该宏对程序执行部分所定义的消息映射进行初始化。 约定:全程函数以“Afx”为前缀,所有全程变量都是以“afx”为前缀,宏不带任何特别前缀,但是全部大写。,消息处理函数 消息处理函数:指的是与某个消息对应的函数。 消息处理函数的执行是由其对应的消息引发的,这个机制构成了Windows程序控制流程的基础。 某个类中的消息处理函数是与这个类能够得到的一个消息对应的,当这个消息发生时,这个函数就会被执行。,消息处理函数的使用与一般成员函数不同: 一般成员函数包括两部分:函数的声明和函数的实现。定义一个一般成员函数时,在类中声明函数的原型(一般在包含文件中),在实现文件中实现函数的具体代码。 而消息处理函数除了这两个部分以外,还有第三部分:即映射部分。,消息处理函数的声明方法与一般成员函数也不相同。 以下对各类消息处理函数的声明、映射的方法进行讨论。 1. 窗口消息处理

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论