MFC应用程序概述 (2).ppt
第第3章章 MFC应用程序概述应用程序概述MFC应用程序概述应用程序概述Windows 应用程序概述应用程序概述MFC应用程序框架应用程序框架文档文档/视图结构视图结构消息映射消息映射3.1 Windows 应用程序概述应用程序概述3.1.1 窗口编程基础窗口编程基础l窗口窗口l消息和消息队列消息和消息队列l事件驱动的程序设计事件驱动的程序设计l资源管理资源管理1.窗口窗口(Window)l窗口是应用程序与用户交互的界面窗口是应用程序与用户交互的界面l窗口元素以对象方式组织窗口元素以对象方式组织l一个应用程序由多个窗口组成一个应用程序由多个窗口组成l程序运行过程是窗口之间,窗口与系统,程序运行过程是窗口之间,窗口与系统,窗口与用户之间交换并处理数据的过程。窗口与用户之间交换并处理数据的过程。2.窗口的界面元素窗口的界面元素垂直滚动条垂直滚动条标题栏标题栏菜单栏菜单栏关闭按钮关闭按钮最小化按钮最小化按钮最大化按钮最大化按钮水平滚动条水平滚动条窗口边界窗口边界客户区客户区消息消息(Message)和消息队列和消息队列 l消息用于通知某个事件的产生消息用于通知某个事件的产生l消息机制消息机制lMSGl消息的类型消息的类型消息消息(Message)和消息队列和消息队列lWindows应用程序是利用消息与其他应用程序是利用消息与其他Windows应用程序和操作系统进行信息应用程序和操作系统进行信息交换的。交换的。l消息的作用是通知一个应用程序某个确消息的作用是通知一个应用程序某个确定的事件的产生。定的事件的产生。l应用程序对该事件做出响应,即编写相应用程序对该事件做出响应,即编写相应的消息处理代码。应的消息处理代码。举例:按下鼠标左键时,系统会产生举例:按下鼠标左键时,系统会产生WM_LBUTTONDOWN消息消息消息消息(Message)和消息队列和消息队列Windows应用程序接受系统队列传递过来应用程序接受系统队列传递过来的消息的步骤:的消息的步骤:(1)每个每个Windows应用程序都有一个应用程序都有一个WinMain()函数函数,在该函数中会定义一个在该函数中会定义一个窗口句柄窗口句柄,当应用程序启动时,会使该窗口句柄注当应用程序启动时,会使该窗口句柄注册,操作系统使用窗口句柄与册,操作系统使用窗口句柄与Windows应用程序通信。应用程序通信。消息消息(Message)和消息队列和消息队列(2)Windows应用程序创建一个或多个窗口,应用程序创建一个或多个窗口,每个窗口都有一个窗口处理函数每个窗口都有一个窗口处理函数(WndProc),负责窗口显示和响应用户输,负责窗口显示和响应用户输入。入。(3)消息映射消息映射(Message Mapping):负责从:负责从消息队列中取消息,并送回窗口,由窗消息队列中取消息,并送回窗口,由窗口处理函数选择合适的消息处理函数响口处理函数选择合适的消息处理函数响应消息。应消息。派送消息消息源1消息源2消息源n否程序开始程序结束捕获消息处理消息是否退出消息是消息机制消息机制消消息息机机制制是是Windows应应用用程程序序运运行行的的核核心心工工作作机制,用如下机制,用如下结构体结构体MSG表示:表示:typedef struct tagMSG HWND hwnd;UINT message;WPARAM wParam;LPARAM lParam;DWORD time;POINT pt;MSG;MSG结构体成员说明:结构体成员说明:(1)hwnd 接收消息的窗口句柄。接收消息的窗口句柄。(2)Message 消息值,每个消息值,每个windows消息都有一个消消息都有一个消息值,该值由息值,该值由windows.h头文件的宏定头文件的宏定义来标识。义来标识。(3)wParam和和lParam 包含有关消息的附加信息,它随消息的不同而包含有关消息的附加信息,它随消息的不同而不同。不同。(4)Time 指定消息送至队列的时间界限。指定消息送至队列的时间界限。(5)pt 指定消息发送时屏幕光标的位置,结构如下:指定消息发送时屏幕光标的位置,结构如下:typedef struct tagPOINT LONG x;LONG y;POINT;消息的类型消息的类型1.输入消息输入消息 由键盘和鼠标操作产生输入消息。这由键盘和鼠标操作产生输入消息。这类消息首先放在系统消息队列中,后由类消息首先放在系统消息队列中,后由Windows操作系统将他们放到应用程序操作系统将他们放到应用程序消息队列中,由应用程序处理消息。消息队列中,由应用程序处理消息。2.控件消息控件消息 用户操作窗口对象时产生控件消息,用户操作窗口对象时产生控件消息,这类消息一般不进入应用程序消息队列,这类消息一般不进入应用程序消息队列,而直接发送到控件对象所属的对话框窗而直接发送到控件对象所属的对话框窗口口消息的类型消息的类型3.系统消息系统消息 对程序化的事件或系统时钟中断做出的放对程序化的事件或系统时钟中断做出的放映。一类例如映。一类例如DDE(动态数据交换消息动态数据交换消息)要通过要通过Windows的系统消息队列,送入应用程序的的系统消息队列,送入应用程序的消息队列,另一类直接送入应用程序的消息队消息队列,另一类直接送入应用程序的消息队列,例如创建窗口消息。列,例如创建窗口消息。4.用户消息用户消息 是程序员自己定义并在应用程序中主动发出是程序员自己定义并在应用程序中主动发出的,一般由应用程序的某一部分做内部处理。的,一般由应用程序的某一部分做内部处理。3.事件驱动的程序设计事件驱动的程序设计lWindowsWindows操作系统下的操作系统下的WindowsWindows应用程序应用程序采用事件驱动的程序设计,与采用事件驱动的程序设计,与DosDos操作系操作系统下面向过程有明显不同。统下面向过程有明显不同。l事件驱动的程序的逻辑顺序是按事件的事件驱动的程序的逻辑顺序是按事件的产生而决定的。产生而决定的。l事件的产生不是预先定义的,有着随机事件的产生不是预先定义的,有着随机性性。3.事件驱动的程序设计事件驱动的程序设计例例1、一个应用程序的功能是体操全能比赛、一个应用程序的功能是体操全能比赛项目运动成绩管理,体操全能包括项目运动成绩管理,体操全能包括4个项个项目,在一个驱动中需要如下步骤:目,在一个驱动中需要如下步骤:(1)输入第一项运动员的成绩。输入第一项运动员的成绩。(2)输入第二项运动员的成绩。输入第二项运动员的成绩。(3)输入第三项运动员的成绩。输入第三项运动员的成绩。(4)输入第四项运动员的成绩。输入第四项运动员的成绩。(5)计算每个运动员的总分。计算每个运动员的总分。(6)按总分排名。按总分排名。开始开始输入第一项某运动员的输入第一项某运动员的成绩成绩输入第二项某运动员的输入第二项某运动员的成绩成绩输入第三项某运动员的输入第三项某运动员的成绩成绩输入第四项某运动员的输入第四项某运动员的成绩成绩计算每个运动员计算每个运动员的总分的总分按总分排名按总分排名结束结束消息消息循环循环事件驱动程序流程示例事件驱动程序流程示例4.资源管理资源管理l资源的类型资源的类型l用户自定义资源用户自定义资源l菜单菜单l对话框对话框l工具栏工具栏l系统资源系统资源l设备上下文设备上下文l画刷画刷l画笔画笔l字体字体l通信端口通信端口3.1.2 Windows应用程序组成应用程序组成一个应用程序是如何开始?一个应用程序是如何开始?l操作系统创建一个新的进程和一个初始操作系统创建一个新的进程和一个初始线程线程l应用程序代码装载到内存应用程序代码装载到内存l动态链接库装载到内存动态链接库装载到内存(如果需要使用如果需要使用DLL)l为数据和堆栈分配物理内存,并映射到为数据和堆栈分配物理内存,并映射到虚拟内存虚拟内存l应用程序开始执行应用程序开始执行3.1.2 Windows应用程序组成应用程序组成Windows应用程序必须包含两个基本函数:应用程序必须包含两个基本函数:(1)应用程序主函数应用程序主函数WinMain()WinMain函数定义了窗口句柄,创建初函数定义了窗口句柄,创建初始化窗口并启动一个消息循环。始化窗口并启动一个消息循环。(2)窗口处理函数窗口处理函数WinProc()WinProc函数处理所有从操作系统传递函数处理所有从操作系统传递到窗口的消息。每一个窗口都要有一个窗口到窗口的消息。每一个窗口都要有一个窗口处理函数。处理函数。3.1.2 Windows应用程序组成应用程序组成1.WinMain()函数函数 Windows应用程序是从应用程序是从WinMain()函数开始函数开始和结束的。和结束的。在在”WINBASE.H”中定义如下:中定义如下:int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSR lpCmdLine,int nCmdShow );3.1.2 Windows应用程序组成应用程序组成参数说明如下:参数说明如下:(1)hInstance 系统分配的窗口所属的应用程序的实例系统分配的窗口所属的应用程序的实例句柄,标识当前进程的实例,是进程所句柄,标识当前进程的实例,是进程所占据的地址空间的首地址,是程序的唯占据的地址空间的首地址,是程序的唯一标识。一标识。(2)hPrevInstance 用于检查是否有多个程序实例运行。用于检查是否有多个程序实例运行。3.1.2 Windows应用程序组成应用程序组成(3)lpCmdLine 是一个指向字符串的指针,用来保存是一个指向字符串的指针,用来保存程序运行时的参数,同程序运行时的参数,同main函数中的函数中的argv 相似。相似。(4)nCmdShow 用来指明应用程序的主窗口的显示用来指明应用程序的主窗口的显示方式方式(最大化,最小化,一般显示最大化,最小化,一般显示),通,通常被常被ShowWindow()函数作为显示窗口函数作为显示窗口的参数。的参数。3.1.2 Windows应用程序组成应用程序组成WinMain函数的作用:函数的作用:注册窗口类,创建并初始化窗口,注册窗口类,创建并初始化窗口,创建消息循环创建消息循环(message loop)。(1)注册窗口类注册窗口类 每个窗口都包含一些基本属性,如窗每个窗口都包含一些基本属性,如窗口边框、标题、大小、位置、鼠标、背口边框、标题、大小、位置、鼠标、背景色等,注册的过程是将这些属性报告景色等,注册的过程是将这些属性报告给系统。给系统。3.1.2 Windows应用程序组成应用程序组成(2)创建并初始化窗口创建并初始化窗口 CreateWindow()函数用于创建窗口,函数用于创建窗口,定义了窗口的名称、位置、尺寸等数据,定义了窗口的名称、位置、尺寸等数据,创建成功返回窗口句柄,否则为创建成功返回窗口句柄,否则为0。创建后创口需要调用创建后创口需要调用ShowWindow()和和UpdateWindow()两个函数显示窗口。两个函数显示窗口。3.1.2 Windows应用程序组成应用程序组成(3)创建消息循环创建消息循环 使用使用While语句创建一个消息循环,负责从语句创建一个消息循环,负责从消息队列中获取消息并发送给相应的处理函数。消息队列中获取消息并发送给相应的处理函数。while(GetMessage (&Msg,NULL,0,0)TranslateMessage(&Msg);DispatchMessage(&Msg);TranslateMessage()函数的作用是将来自键函数的作用是将来自键盘的命令翻译为消息的盘的命令翻译为消息的ID字符表示。字符表示。DispatchMessage()把每个消息分发给相应的把每个消息分发给相应的窗口函数。窗口函数。3.1.2 Windows应用程序组成应用程序组成2.窗口处理函数窗口处理函数 决定窗口在它的客户区中显示哪些内容、窗决定窗口在它的客户区中显示哪些内容、窗口如何响应用户输入,窗口函数定义如下:口如何响应用户输入,窗口函数定义如下:LRESULT CALLBACK WndProc(HWND hwnd,UNIT Message,WPARAM wParam,LPARAM lparam,)3.1.2 Windows应用程序组成应用程序组成参数说明如下:参数说明如下:(1)LRESULT 表示该函数返回值为长整数,由系统使用。表示该函数返回值为长整数,由系统使用。(2)CALLBACK 表示该函数是回调函数,由系统使用。表示该函数是回调函数,由系统使用。(3)Hwnd 接收消息的窗口句柄接收消息的窗口句柄(4)Message用来标示消息的数字用来标示消息的数字(5)wParam和和lparam两个两个32位的消息参数,用来提供消息的附加信息。位的消息参数,用来提供消息的附加信息。Windows的编程模型与的编程模型与MS-DOS编编程模型之比较程模型之比较 l第一,用第一,用C语言编写基于语言编写基于MS-DOS的应用程序时,的应用程序时,唯一绝对需要的是一个名为唯一绝对需要的是一个名为main的函数。而当的函数。而当Windows操作系统启动一个程序时,调用的是操作系统启动一个程序时,调用的是WinMain函数。函数。l第二,许多第二,许多MS-DOS程序直接写显存和打印机接程序直接写显存和打印机接口。这种技术的不利之处是对每一种设备需要其口。这种技术的不利之处是对每一种设备需要其支持的驱动程序软件。支持的驱动程序软件。Windows引入了一个名引入了一个名为图形设备接口(为图形设备接口(GDI)的抽象化外层,所以用)的抽象化外层,所以用户不必知道有关系统设备的类型。户不必知道有关系统设备的类型。Windows程程序不是寻址硬件,而是调用序不是寻址硬件,而是调用GDI函数。函数。Windows的编程模型与的编程模型与MS-DOS编程模型之比较编程模型之比较l第三,要在第三,要在MS-DOS环境下进行数据驱动编环境下进行数据驱动编程,必须或者为把数据编码成为初始化常量程,必须或者为把数据编码成为初始化常量或者提供独立的数据文件让程序来读。进行或者提供独立的数据文件让程序来读。进行Windows编程时,使用大量已经确立的格式编程时,使用大量已经确立的格式在资源文件中存储数据。在资源文件中存储数据。l第四,在第四,在MS-DOS环境下一个程序的所有对环境下一个程序的所有对象模块在建立过程中是静态连接的。象模块在建立过程中是静态连接的。Windows允许动态链接,这意味着特别创建允许动态链接,这意味着特别创建的库可以在运行时加载和链接。多个应用程的库可以在运行时加载和链接。多个应用程序可以共享动态链接库(序可以共享动态链接库(DLLs),它节省内),它节省内存和磁盘空间。动态链接增加了程序的模块存和磁盘空间。动态链接增加了程序的模块性。性。3.1.3 应用程序举例应用程序举例 分析使用分析使用AppWizard生成的生成的Win32窗窗口程序示例口程序示例Exam3_2,并对该程序作以,并对该程序作以下修改:下修改:(1)修改输出的文本字符串修改输出的文本字符串”Hello World”为为”Hello C+!”。(2)在视图的中央输出文本在视图的中央输出文本”Starting your VC+learning!”(3)添加一个对话框,并能使用菜单调用这添加一个对话框,并能使用菜单调用这个对话框。个对话框。3.2 MFC应用程序框架应用程序框架lVisual C+6.0是一种集成开发环境,提供了MFC类库。lMFC(Microsoft基本类库,Microsoft Foundation Class Library)lMFC是微软公司对大部分标准的Win32 API函数的封装,提供了图形环境应用程序的框架及创建应用程序的组件.MFC 简简 介介lMFC是用来写是用来写Windows应用程序的应用程序的VC+类集,该类集以层次结构组织起来。类集,该类集以层次结构组织起来。提供的类库对程序设计高度抽象,使代码提供的类库对程序设计高度抽象,使代码的可靠性和重用性得到很大的提高。的可靠性和重用性得到很大的提高。lMFC给给Windows系统开发平台程序员以系统开发平台程序员以最好支持的基本类结构,它包含的类分层最好支持的基本类结构,它包含的类分层结构和功能是具有可伸缩性,在功能扩展结构和功能是具有可伸缩性,在功能扩展的同时,的同时,MFC还保持了程序的向下兼容性。还保持了程序的向下兼容性。MFC类的层次结构类的层次结构lMFC类库中是以层次结构的方式类库中是以层次结构的方式组织起来的,每个层次结构都与一组织起来的,每个层次结构都与一具体的具体的Windows的实体相对应。的实体相对应。l大多数大多数MFC类是从类是从3个基类个基类(CObject类、类、CCmdTarget类、类、CWnd类)派生的类)派生的MFC类的层次结构类的层次结构l根类:根类:CObject类类CObject类类 CCmdTarget类类CWnd类类l从从CObject类派生的类具有运行时获类派生的类具有运行时获得对象大小的名字的能力得对象大小的名字的能力l从从CCmdTarget类派生的类能够处类派生的类能够处理命令消息理命令消息l从从CWnd类派生的类能够控制窗口类派生的类能够控制窗口派生派生派生派生CObject派生类派生类CObjectCCmdTargetCWinThreadCWinAppCWndCFrameWndCViewCDocumentMFC类的层次结构类的层次结构lMFC提供的一些重要的类分为以下几种:v应用程序框架结构类CWinAppv程序窗口类CFramWndv图形打印类CGdiObjectv文件类CFilevInternet类v集合类v异常和调试支持类应用程序类应用程序类CWinAppl应用程序框架类主要包括应用程序应用程序框架类主要包括应用程序类、线程类、文档类和文档模板类。类、线程类、文档类和文档模板类。l应用程序类应用程序类CWinApp:每个每个MFC应应用程序只能由一个用程序只能由一个CWinApp的派生的派生对象。对象。lCWinApp是应用程序开始后创建的是应用程序开始后创建的第一个对象,结束前最后一个执行第一个对象,结束前最后一个执行对象。对象。文档类文档类CDocumentl文档类文档类Cdocument封装了应用封装了应用程序的数据管理功能,可以存程序的数据管理功能,可以存储和载入用户定义的持久数据储和载入用户定义的持久数据提供提供“容器容器”l文档类负责将一个文档赋给它文档类负责将一个文档赋给它的成员变量,并允许视图类编的成员变量,并允许视图类编辑这些成员变量。辑这些成员变量。程序窗口类程序窗口类CWndl程序窗口类主要包括框架窗口类、对程序窗口类主要包括框架窗口类、对话框类、视图类、控件类等。话框类、视图类、控件类等。l类类CWnd提供了提供了MFC中所有窗口类的中所有窗口类的基本功能,作为所有类的公共基类。基本功能,作为所有类的公共基类。l创建一个创建一个Windows窗口需二步,首窗口需二步,首先引入构造函数,构造一个先引入构造函数,构造一个CWnd对对象,然后调用象,然后调用Create建立建立Windows窗口并将它连接到窗口并将它连接到CWnd对象上。对象上。框架窗口类框架窗口类CFramWndl框架窗口类框架窗口类CFramWnd是是CWnd类的子类,创建和维护窗口的边类的子类,创建和维护窗口的边框、菜单栏、工具栏、状态栏等框、菜单栏、工具栏、状态栏等部分部分.l一个一个SDI应用程序,主框架类是从应用程序,主框架类是从CMainFrame派生的,对于一个派生的,对于一个MDI应用程序,主框架类是从应用程序,主框架类是从CMDIFramWnd派生的。派生的。视图类视图类CViewl视图类是应用程序中较重要的类,视图类是应用程序中较重要的类,应用程序返回的结果大多在视图类应用程序返回的结果大多在视图类上进行进行和显示上进行进行和显示,CView 是用于让是用于让用户通过窗口来访问文档用户通过窗口来访问文档,提供人,提供人机交互的界面。机交互的界面。l视图类负责描述文档的内容,也可视图类负责描述文档的内容,也可以用户编辑文档。以用户编辑文档。l创建应用程序时,创建文档类的一创建应用程序时,创建文档类的一个实例后将创建视图类个实例后将创建视图类Cview的一的一个实例。个实例。几种视图类几种视图类lCView类是基本视类,支持基本操作类是基本视类,支持基本操作lCScrollView类提供了滚动功能,设置滚动类提供了滚动功能,设置滚动尺寸和坐标模式。尺寸和坐标模式。lCFormView类可在资源文件中定义界面的类可在资源文件中定义界面的能力,并可将子窗口和变量进行绑定。能力,并可将子窗口和变量进行绑定。lCListView类利用类利用ListCtrl(列表框列表框)界面作界面作为视界面为视界面lCEditView类利用类利用Edit接收用户输入,具有接收用户输入,具有输入框的一切功能,可实现多行文本的编输入框的一切功能,可实现多行文本的编辑。辑。对话框类对话框类CDialoglCDialog类封装了用来创建对话框的类封装了用来创建对话框的Windows API,在创建时可以用对,在创建时可以用对话框模板中定义的控件来填充。话框模板中定义的控件来填充。lCDialog 可分别处理无模式和有模式可分别处理无模式和有模式两种类型的对话框两种类型的对话框.l几个几个MFC通用对话框类通用对话框类CColorDialog、CFileDialog、CFontDialog、CPrintDialog。控件类和控制栏类控件类和控制栏类l常用控件类常用控件类CButton类,类,CListCtrl类类,CProgressCtrl类类,CTreeCtrl类类,CComboBox类类,CEdit类等。类等。l控制栏类(控制栏类(CControl类的派生类),类的派生类),从编成的角度看,工具栏只是从编成的角度看,工具栏只是CToolBar类的一个对象,状态栏类的一个对象,状态栏是是CStatusBar类的对象。类的对象。MFC应用程序框架分析应用程序框架分析l在一个在一个CHello CHello SDI应用程序中,应用程序中,向导为我们生成了向导为我们生成了4个主要的类,个主要的类,这些类都是这些类都是MFC类的派生类,类的派生类,分别包含在对应的头文件以及实分别包含在对应的头文件以及实现文件中。现文件中。l分析每个类的作用分析每个类的作用 MFC应用程序框架分析应用程序框架分析lCHelloApp类类类类CHelloApp的一个对的一个对象代表一个应用程序。象代表一个应用程序。l程序定义了一个全局程序定义了一个全局CHelloApp对象对象theApp。CWinApp基类决定基类决定theApp的大的大多数行为。多数行为。lCWinAppCWinApp类重载函数:类重载函数:InitInstance()InitInstance(),完成应用的初始化以,与完成应用的初始化以,与WinMainWinMain函数结构函数结构中的初始化处理相对应。中的初始化处理相对应。MFC应用程序框架分析应用程序框架分析l典型的一个应用程序将有一个主应用典型的一个应用程序将有一个主应用程序窗口。因此,程序窗口。因此,CHelloApp 应用程应用程序类定义了一个名为序类定义了一个名为 m_pMainWnd 成员变量来指向主窗口。成员变量来指向主窗口。lInitInstance InitInstance 函数建立了一个函数建立了一个 CHelloWindow CHelloWindow 事例,并使用事例,并使用 m_pMainWnd m_pMainWnd 来指向一个新的窗口来指向一个新的窗口 MFC应用程序框架分析应用程序框架分析lCMainFrameCMainFrame代表的是程序的主框架窗口。代表的是程序的主框架窗口。l框架窗口类及其相关的文件框架窗口类框架窗口类及其相关的文件框架窗口类对应应用程序的主窗口对应应用程序的主窗口,他的定义是在他的定义是在头文件头文件MainFrm.h中,而实现则是在中,而实现则是在MainFrm.cpp文件中。所有与框架窗口文件中。所有与框架窗口相关的功能都是在这里定义和实现的。相关的功能都是在这里定义和实现的。MFC应用程序框架分析应用程序框架分析l文档类及其相关的文件文档类及其相关的文件 文档类在应用程序中没有直观的对应关系,文档类在应用程序中没有直观的对应关系,但这一点就是但这一点就是MFC的框架的一个特点就是的框架的一个特点就是文文档档/视图结构视图结构。可以抽象一点地来理解,比如。可以抽象一点地来理解,比如说我们在说我们在Word中打开了一个文件,其实,这中打开了一个文件,其实,这个文件就是文档,而我们看到的只不过是这个文件就是文档,而我们看到的只不过是这个文件一个视图,所以说文档提供了应用程个文件一个视图,所以说文档提供了应用程序显示的支持,但是我们真正看到的应用程序显示的支持,但是我们真正看到的应用程序显示的则是一个视图,文档类的定义是在序显示的则是一个视图,文档类的定义是在“CHelloDoc.h”中,而他的实现则是在中,而他的实现则是在“CHello Doc.cpp”文件中。文件中。MFC应用程序框架分析应用程序框架分析l视图类及其相关的文件视图类及其相关的文件 视图类是用来显示文档对象的内容的,我视图类是用来显示文档对象的内容的,我们在们在Word程序中所看到的界面就是一个视程序中所看到的界面就是一个视图,我们要修改,画图首先操作的对象就图,我们要修改,画图首先操作的对象就是视图,所以,视图类就如他的名称所指是视图,所以,视图类就如他的名称所指出的那样,提供了从用户角度看到的东西。出的那样,提供了从用户角度看到的东西。视图类的定义在视图类的定义在“CHelloView.h”中,实中,实现是在文件现是在文件“CHelloView.h”中。中。MFC应用程序框架分析应用程序框架分析l应用程序类及其相关的文件应用程序类及其相关的文件 MFC应用程序的初始化,启应用程序的初始化,启动运行和结束都是由应用程序动运行和结束都是由应用程序对象完成的。他对应的文件是对象完成的。他对应的文件是”Hello World.cpp”和和”Hello World.h”。MFC应用程序框架分析应用程序框架分析l 大致的看出大致的看出MFC应用程序应用程序对象之间的关系了。应用程序对象之间的关系了。应用程序一开始生成应用程序对象,然一开始生成应用程序对象,然后,在后,在InitInstance中创建中将中创建中将会创建文档模板对象会创建文档模板对象,应用程应用程序就可以通过建立的模板对象序就可以通过建立的模板对象来管理文档、视图、和框架窗来管理文档、视图、和框架窗口。口。3.3 消息映射消息映射 在在Win32的窗口函数中,采用的窗口函数中,采用switch_case结构进行消息处理结构进行消息处理,在在MFC中通过消息映射的方法,将消息映射到中通过消息映射的方法,将消息映射到各个处理函数。各个处理函数。本节内容包括:本节内容包括:l消息的类别及描述消息的类别及描述l消息映射系统消息映射系统l消息处理的路径消息处理的路径l自定义消息处理自定义消息处理3.3.1 消息的类别消息的类别l lMSG结构描述消息,区别消息一般结构描述消息,区别消息一般是对结构中的主消息是对结构中的主消息message、附加、附加参数参数wParam和和lParam3个字段进行个字段进行判断判断l在在MFC中,消息分为窗口消息,命中,消息分为窗口消息,命令消息和控件消息三种类型。令消息和控件消息三种类型。窗口消息的描述窗口消息的描述1.窗口消息窗口消息 只能被窗口或者窗口对象处理,在只能被窗口或者窗口对象处理,在MFC中油中油CView和和CFrame及其派生类、及自定义窗口及其派生类、及自定义窗口类处理窗口消息。类处理窗口消息。描述:描述:lmessage:WM_XXX lwParam和和 lParam:随:随WM_XXX而变而变 举例举例:WM_LBUTTONDOWN鼠标左键消息鼠标左键消息,wParam是一个整数值,标识鼠标按下是哪个是一个整数值,标识鼠标按下是哪个键,键,lParam的低字节是鼠标的的低字节是鼠标的X坐标,高字节坐标,高字节是鼠标的是鼠标的Y坐标坐标。命令消息的描述命令消息的描述2.命令消息命令消息 选择菜单项、单击工具栏按钮等都可选择菜单项、单击工具栏按钮等都可以产生命令消息,从基类以产生命令消息,从基类CCmdTarget派生的类都能处理命令消息派生的类都能处理命令消息 描述:描述:lmessage:WM_COMMAND lwParam:低:低16位为命令位为命令ID、高、高16位为位为0llParam:0L 控件消息的描述控件消息的描述3.控件消息控件消息 当控件事件发生时,如改变文本框控件的当控件事件发生时,如改变文本框控件的内容、选择列表框控件中某一选项产生内容、选择列表框控件中某一选项产生控件消息,由控件所属的对话框类处理控件消息,由控件所属的对话框类处理描述:描述:lmessage:WM_NOTIFY lwParam:控件:控件ID llParam:指向:指向NMHDR的指针,的指针,NMHDR是包含了消息内容的一个结构是包含了消息内容的一个结构 消息宏前缀消息宏前缀 前缀前缀消息分类消息分类BMBM按钮控制消息按钮控制消息CBCB组合框控制消息组合框控制消息DMDMEMEM默认下压式按钮控制消息默认下压式按钮控制消息编辑控制消息编辑控制消息LBLBSBMSBMWMWM列表框控制消息列表框控制消息滚动条控制消息滚动条控制消息窗口消息窗口消息3.3.2 消息映射系统消息映射系统MFC消息映射由两大块组成:消息映射由两大块组成:l1.CCmdTarget的派生类的派生类l每个子类都能接收和处理消息,并定义了一每个子类都能接收和处理消息,并定义了一个消息映射表个消息映射表l2.2.消息映射。消息映射。MFCMFC提供了提供了3 3个宏管理消息个宏管理消息映射。映射。lDECLARE_MESSAGE_MAP()DECLARE_MESSAGE_MAP()lBEGIN_MESSAGE_MAP()BEGIN_MESSAGE_MAP()lEND_MESSAGE_MAP()END_MESSAGE_MAP()MFC消息映射原理消息映射原理l应用程序开始运行后有一个从应用程序开始运行后有一个从CWinApp派生的对象,等待和处理消息的函数是派生的对象,等待和处理消息的函数是应用程序类的应用程序类的RUN()函数。函数。lRUN()函数将接收到的消息都交给主窗函数将接收到的消息都交给主窗口的窗口函数口的窗口函数OnWndMsg(),由,由OnWndMsg()函数负责将消息分类并交予不同的消息函数负责将消息分类并交予不同的消息处理函数去处理。处理函数去处理。消息映射表消息映射表lMFC在每一个能够接收和处理消息类中,在每一个能够接收和处理消息类中,定义一个消息和消息处理函数静态对照定义一个消息和消息处理函数静态对照表,该表称为消息映射表。该类能够处表,该表称为消息映射表。该类能够处理的所有的消息及其对应的消息处理函理的所有的消息及其对应的消息处理函数的地址都列在该表中。数的地址都列在该表中。在类中加入静态消息映射表在类中加入静态消息映射表l在在.h 文件中加入:文件中加入:DECLARE_MESSAGE_MAP()l在在.CPP文件中加入:文件中加入:BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)ON_WM_PAINT().END_MESSAGE_MAp()消息映射表示例消息映射表示例BEGIN_MESSAGE_MAP(CExam1_1App,CWinApp)/AFX_MSG_MAP(CExam1_1App)/AFX_MSG_MAP(CExam1_1App)ON_COMMAND(ID_APP_ABOUT,OnAppAbout)ON_COMMAND(ID_APP_ABOUT,OnAppAbout)/AFX_MSG_MAP/AFX_MSG_MAPON_COMMAND(ID_FILE_NEW,ON_COMMAND(ID_FILE_NEW,CWinApp:OnFileNew)CWinApp:OnFileNew)ON_COMMAND(ID_FILE_OPEN,ON_COMMAND(ID_FILE_OPEN,CWinApp:OnFileOpen)CWinApp:OnFileOpen)ON_COMMAND(ID_FILE_PRINT_SETUP,ON_COMMAND(ID_FILE_PRINT_SETUP,CWinApp:OnFilePrintSetup)CWinApp:OnFilePrintSetup)END_MESSAGE_MAP()消息处理宏格式消息处理宏格式消息类型消息类型宏格式宏格式参数参数预预定定义义窗窗口口消息消息ON_WM_XXXON_WM_XXX无无命令消息命令消息ON_COMMANDON_COMMAND命命令令IDID,消消息息处处理理函数名函数名更更新新命命令令消消息息ON_UPDATE_COMMON_UPDATE_COMMAND_UIAND_UI命命令令IDID,消消息息处处理理函数名函数名控件消息控件消息ON_XXXON_XXX控控件件IDID,消消息息处处理理函数名函数名用用户户自自定定义义消息消息ON_MESSAGEON_MESSAGE自自定定义义消消息息IDID,消消息处理函数名息处理函数名l例例3-3创建一个单文档的创建一个单文档的MFCMFC应用程序应用程序Exam3_3Exam3_3,并实现功能:当在视图中,并实现功能:当在视图中双击鼠标右键时,弹出对话框,显双击鼠标右键时,弹出对话框,显示鼠标的坐标。示鼠标的坐标。如何处理窗口消息如何处理窗口消息所有基类均没定义该消息的处理函数窗口类窗口类:OnWndMsg(.)是窗口消息是窗口消息搜索窗口类的消息映射表搜索窗口类的消息映射表找到找到?继续搜索基类消息映射表继续搜索基类消息映射表窗口类窗口类:DefWndProc(.)执行消息处理函数执行消息处理函数命令消息或控件消息处理命令消息或控件消息处理找到消息处理函数yesnoyesno3.3.3 消息处理路径消息处理路径窗口消息的处理:窗口消息的处理:lOnWndMsg()搜索窗口类的消息映射表,搜索窗口类的消息映射表,如果找到了匹配的消息处理函数,就执如果找到了匹配的消息处理函数,就执行消息处理函数行消息处理函数 l如果找不到,继续搜索该窗口类的基类,如果找不到,继续搜索该窗口类的基类,如果找到了匹配的消息处理函数,就执如果找到了匹配的消息处理函数,就执行消息处理函数;行消息处理函数;l如果还没有找到,则把消息交给默认窗如果还没有找到,则把消息交给默认窗口函数口函数DefWindowProc()处理处理 如何处理命令消息如何处理命令消息l从理论上讲,所有从基类从理论上讲,所有从基类 CCmdTarget类派生的类均可处理命令消息,类派生的类均可处理命令消息,MFC应应用程序框架将依次检查基本类的消息映用程序框架将依次检查基本类的消息映射表。射表。视图类视图类文档类文档类文档模板类文档模板类框架窗口类框架窗口类应用程序类应用程序类界面变灰界面变灰命令消息的处理命令消息的处理lOnWndMsg()函数会将命令消息分发给窗口类函数会将命令消息分发给窗口类的的OnCommand()函数函数lOnCommand()函数调用成员函数函数调用成员函数OnCmdMsg()函数,该函数依次搜索视图类、文档类、文函数,该函数依次搜索视图类、文档类、文档模板类、框架窗口类和应用程序类及其基类档模板类、框架窗口类和应用程序类及其基类中的消息映射表,搜索到消息处理函数,中的消息