MFC消息机制详解
- 格式:doc
- 大小:196.00 KB
- 文档页数:44
mfc的原理、机制与开发实例MFC(Microsoft Foundation Class)是微软公司开发的一套面向对象的应用程序框架,用于简化Windows操作系统上的图形用户界面(GUI)应用程序的开发。
MFC提供了一系列的类和函数,使开发者能够更加方便地创建、管理和操作窗口、对话框、控件等GUI元素。
MFC的原理和机制主要基于C++语言和Windows操作系统的API (Application Programming Interface)。
MFC的核心类是CObject类,所有的MFC类都是从CObject类派生而来的。
MFC使用了一种称为消息映射(Message Mapping)的机制来处理用户界面的事件和消息。
当用户进行操作时,例如点击按钮、输入文本等,Windows操作系统会生成相应的消息,并将其发送给应用程序。
MFC通过消息映射将这些消息与相应的处理函数关联起来,从而实现对用户操作的响应。
MFC的开发实例可以通过一个简单的计算器程序来说明。
首先,我们需要创建一个对话框,用于显示计算器的界面。
在MFC中,可以使用CDialog类来创建对话框。
然后,我们需要在对话框中添加一些控件,例如按钮、文本框等,用于用户输入和显示计算结果。
在MFC中,可以使用CButton、CEdit等类来创建这些控件。
接下来,我们需要处理用户的操作。
例如,当用户点击按钮时,我们需要执行相应的计算操作。
在MFC中,可以通过消息映射来实现。
首先,我们需要在对话框类中添加一个消息映射函数,用于处理按钮的点击事件。
然后,我们需要在消息映射函数中编写相应的代码,例如获取用户输入的数字、进行计算等。
最后,我们需要将消息映射函数与按钮关联起来,以便在用户点击按钮时调用相应的函数。
除了处理用户的操作,MFC还提供了许多其他功能,例如文件操作、数据库访问、图形绘制等。
开发者可以根据自己的需求选择相应的MFC类和函数来实现这些功能。
MFC(Microsoft Foundation Classes)是一种用于开发Windows应用程序的C++类库,它建立在Win32 API之上,并提供了更高层次的抽象和封装。
在MFC中,消息机制是实现应用程序与用户交互和事件处理的基础。
MFC消息机制的原理如下:1.消息映射表:在MFC应用程序中,每个窗口类(如对话框类、视图类等)通常都有一个消息映射表(message map),用于将消息与相应的处理函数关联起来。
消息映射表是一个静态数据结构,通过DECLARE_MESSAGE_MAP宏进行声明,并在类的实现文件中使用BEGIN_MESSAGE_MAP和END_MESSAGE_MAP宏定义映射表的内容。
2.消息处理函数:每个消息映射表项将消息的ID(或者命令ID)与相应的消息处理函数绑定在一起。
消息处理函数是成员函数,由开发人员根据需要自行定义。
当相应的消息被触发时,系统会自动调用与该消息对应的处理函数。
3.消息循环:MFC应用程序在运行时通过消息循环(message loop)不断接收和分发消息。
消息循环负责从操作系统获取消息,并将消息派发给目标窗口的消息处理函数进行处理。
消息循环可以使用Run函数或AfxGetApp()->Run函数启动。
4.分发消息:当系统从消息队列中获取到一个消息后,会根据消息的目标窗口通过HWND来查找对应的CWnd对象,并调用该窗口的响应函数(如PreTranslateMessage、OnCmdMsg等)进行消息处理。
如果消息在目标窗口的消息映射表中找到了对应的处理函数,则将该消息转发给对应的处理函数进行处理。
5.消息处理:消息处理函数执行相应的逻辑,可以进行界面更新、控件操作、数据处理等操作。
处理函数的返回值通常是布尔型,表示是否终止消息的传递。
通过这种消息机制,MFC应用程序可以实现用户交互和事件处理的功能,使开发人员可以方便地处理窗口消息,响应用户操作,以及完成界面和数据之间的交互。
mfc消息机制
MFC(Microsoft Foundation Class)是微软开发的一种面向对象的C++框架,用于Windows操作系统的应用程序开发。
MFC消息机制是MFC框架的核心之一,其基本原理是在窗口、控件等对象之间传递消息,以便处理事件和交互。
具体而言,MFC消息机制包括以下几个方面:1.消息循环:MFC使用一个消息循环来接受和处理Windows操作系统发送的Windows消息,处理完消息后将处理结果反馈给Windows操作系统。
2.消息映射:MFC中的控件和窗口都有一个关联的消息映射表,用于将Windows消息映射到应用程序代码中的相应处理函数上。
当某个控件或窗口收到消息后,根据消息类型在相应的消息映射表中查找对应的消息处理函数,并调用相应的处理函数处理消息。
3.消息类型:MFC处理的Windows消息类型包括键盘和鼠标消息、定时器消息、系统负载消息、窗口大小变化消息等等,具体的消息类型可以在MFC框架的文档中查找。
4.消息处理函数:MFC中的消息处理函数是C++成员函数,定义为afx_msg 修饰的函数,Windows消息处理函数命名时需要遵循一定的命名规则,例如OnPaint()函数用于处理绘图事件。
需要注意的是,MFC消息机制是针对Windows操作系统设计的,其他操作系统可能具有不同的消息机制。
此外,MFC框架已经不是微软推荐的最先进的应用程序开发框架,已经逐渐被其他框架和技术所取代,例如.NET Framework,WPF,UWP等。
MFC原理结构说明MFC(Microsoft Foundation Classes)是一种在Windows平台上开发图形用户界面(GUI)的框架。
MFC提供了一组类、函数和宏,用于简化Windows应用程序开发过程。
本文将对MFC的原理和结构进行详细说明。
一、MFC的原理1. 类与对象:MFC使用面向对象的编程模型,所有的窗口、控件、消息处理程序等都是通过类来定义和创建的。
每个MFC应用程序都包含一个CWinApp类的对象,这个对象是整个应用程序的入口点。
2. 消息映射机制:在MFC中,消息是Windows事件的一种表示。
MFC使用消息映射机制来处理这些消息。
消息映射机制是程序员在类中定义的一种技术,它将特定消息与对应的消息处理函数关联起来。
当收到消息时,MFC会自动调用相应的消息处理函数进行处理。
3. 消息与事件:在MFC中,消息是Windows事件的抽象表示,而事件是用户界面中的交互行为。
MFC提供了一系列预定义的消息类型,如鼠标点击、按键、窗口关闭等,程序员只需要在类中覆盖对应的消息处理函数,就可以处理这些消息。
4. 窗口类和控件类:在MFC中,窗口类和控件类是界面元素的基础。
MFC提供了一组窗口类(如CWnd、CFrameWnd)和控件类(如CButton、CEdit),程序员可以通过继承这些类来创建自定义的窗口和控件。
5. 文档视图模型:MFC中引入了文档视图模型(Document-View Model)的概念,用于实现应用程序的数据和界面的分离。
文档类(CDocument)管理应用程序的数据,视图类(CView)用于显示数据,而框架窗口类(CFrameWnd)则用于协调文档和视图之间的交互。
二、MFC的结构1. 应用程序类(CWinApp):应用程序类是MFC应用程序的入口点,它派生自CWinApp类。
应用程序类负责初始化应用程序的环境,包括注册窗口类、创建主窗口、加载并运行消息循环等。
深入探讨MFC消息循环和消息泵MFC(Microsoft Foundation Class)是一个用于开发Windows应用程序的C++类库。
在MFC中,消息循环和消息泵是非常重要的概念,它们负责处理和分发用户输入、系统事件等各种消息。
消息循环是一个无限循环,用于接收和分发各种消息。
在应用程序的主线程中,消息循环会不断的从操作系统中获取消息,并调用相应的处理函数来处理消息。
当所有消息处理完毕后,消息循环会继续从操作系统中获取下一个消息。
这个过程会持续进行,直到应用程序退出。
消息泵是消息循环的核心部分,它负责从操作系统获取消息,并将消息添加到消息队列中。
消息泵会不断的从消息队列中取出消息,并将消息发送给对应的窗口的消息处理函数。
在MFC中,消息泵主要由主消息循环函数CWinApp::Run来实现。
CWinApp是一个用于管理应用程序的类,它派生自CWinThread类。
在CWinApp::Run函数中,首先会调用PreMessageLoop函数,对应用程序进行一些初始化操作。
然后,进入消息循环,并依次处理消息。
在每次迭代中,消息泵会不断地从消息队列中取出消息,并将消息发送给对应的窗口进行处理。
处理完当前消息后,消息泵会继续从消息队列中取出下一个消息,并重复以上的操作。
MFC中的消息循环和消息泵机制保证了应用程序能够及时响应用户的输入和系统事件。
当用户在应用程序中进行操作时,比如点击窗口、按下快捷键等,这些操作都会被转化为消息,并通过消息循环和消息泵传递给应用程序进行处理。
应用程序可以根据收到的消息来更新界面、执行相应的功能等。
消息循环和消息泵的深入理解对于开发MFC应用程序非常重要。
在消息循环中,开发者可以插入一些自定义的处理逻辑,比如处理自定义的消息、扩展窗口处理函数等。
在消息泵中,开发者可以了解消息的分发机制,比如哪些消息是窗口消息、哪些消息是系统消息等。
通过对消息循环和消息泵的深入理解,开发者可以更加灵活地控制应用程序的行为,增加应用程序的交互性和可扩展性。
MFC消息映射机制过程1:windows OS事件驱动策略基于3种消息。
标准消息、通告消息、命令消息。
2:“事件”就是“消息”,事件是有形形象的,是站在⼈类能理解的⾓度来定义的。
消息是⽆形抽象的,是站在OS能理解的⾓度来定义的。
3:我把按下⿏标左键这⼀事件转换成WM_LBUTOONDOWN消息来告诉OS我做了按下⿏标左键这了件事情。
现在OS知道了我做了按下⿏标左键这了件事情了,那么OS怎么处理呢?3.1:消息响应函数原型//{{AFX_MSG(CMyView)afx_msg void OnLButtonDown(UINT nFlags,CPoint point);//}}AFX_MSGDECLARE_MESSAGE_MAP()3.2:ON_WM_LBUTTONDOWN消息映射宏BEGIN_MESSAGE_MAP(CMyView, CView)//{{AFX_MSG_MAP(CMyView)ON_WM_LBUTTONDOWN()//}}AFX_MSG_MAP// Standard printing commandsON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)END_MESSAGE_MAP()3.3:消息响应函数的定义void CMyView::OnLButtonDown(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call defaultMessageBox("WM_LBUTTONDOWN");CView::OnLButtonDown(nFlags, point);}4:⾄此,我们从按下⿏标左键到看到如下图的效果,OS完成了对事件做出的反应。
mfc 信息机制MFC信息机制MFC(Microsoft Foundation Class)是微软公司推出的一套用于Windows操作系统的C++类库,它为开发者提供了丰富的工具和组件,用于快速构建Windows应用程序。
在MFC中,信息机制是其重要特性之一,它提供了一种方便的方式来管理和传递应用程序中的消息。
一、消息机制的基本概念在MFC中,消息是指应用程序中发生的各种事件,比如鼠标点击、键盘输入、窗口关闭等。
消息机制是指MFC框架中的一套机制,用于处理和分发这些消息。
消息的处理过程包括两个关键组件:消息映射和消息处理函数。
1. 消息映射消息映射是指将消息和消息处理函数进行关联的过程。
通过在类的消息映射表中添加相应的消息和处理函数的映射关系,可以告诉MFC框架在收到某个消息时应该调用哪个函数进行处理。
消息映射表一般定义在类的声明中,使用宏来声明消息映射表的内容。
2. 消息处理函数消息处理函数是指用于处理特定消息的函数。
当MFC框架收到某个消息时,会根据消息映射表中的映射关系调用相应的消息处理函数。
消息处理函数可以是类的成员函数,也可以是全局函数,具体取决于消息映射表中的声明方式。
二、消息机制的应用场景消息机制在MFC中广泛应用于用户界面的交互和事件响应。
通过消息机制,开发者可以方便地处理用户的操作和系统的事件,实现各种功能和交互效果。
1. UI事件响应在MFC应用程序中,用户通过与界面上的控件进行交互来触发各种事件,比如按钮点击、菜单选择等。
通过消息机制,我们可以将这些事件与相应的处理函数进行关联,当用户触发某个事件时,可以执行相应的处理逻辑。
2. 窗口消息处理MFC中的窗口是指用户界面上的各种窗口元素,比如对话框、窗口、视图等。
窗口消息是指与窗口相关的各种事件,比如窗口创建、大小改变、关闭等。
通过消息机制,我们可以对窗口消息进行处理,实现窗口的初始化、布局、关闭等功能。
3. 自定义消息除了系统定义的消息类型,MFC还支持自定义消息。
MFC消息机制⼀、消息的分类1、队列消息、⾮队列消息l队列消息:windows为每个应⽤程序都建⽴⼀个消息队列,那么通过消息队列,进⾏传送的消息都属于队列消息;⼀般来说,由⿏标、键盘产⽣的消息都属于队列消息。
(为什么呢?想想,⿏标、键盘事件都是由系统捕获的,系统捕获后要传递给应⽤程序,就⼀定的通过消息队列);l⾮队列消息:除了队列消息,剩下的⾃然⽽然就是⾮队列消息了;u队列消息是通过PostMessage()的⽅式投递消息的,这样的消息发送也叫“寄送”,该函数寄送消息即可返回,不需要等待程序处理结果;u⾮队列消息是通过SendMessage()的⽅式进⾏的,这样的消息发送叫“发送”;消息不需要进⼊窗⼝的消息队列,然⽽不管是队列消息,还是⾮队列消息,消息处理的起点都是AfxWndProc。
不同的是队列消息,是操作系统把消息投放到消息队列,应⽤程序空闲是,通过⼀个消息循环,搜索消息队列,不停的从消息队列抓取消息,并处理。
⼤致流程是:CwinThread->PumpMessage->CWnd->PreTranslateMessage->…………..->USER32内核->AfxWndProcBase->AfxWndProc->…….(继续处理)⽽⾮队列消息呢(即通过SendMessage⽅式发送的消息)?它是直接进⼊了USER32内核,然后处理的流程和队列消息⼀样了。
注意,不管是队列消息,还是⾮队列消息,都是从USER32内核开始,转到了AfxWndProcBase(有时候不经过这⾥),再到AfxWndProc,所以可以认为AfxWndProc是消息传递与处理的起点!出来后,不管是队列消息,还是⾮队列消息,应该由Windosw系统发往各个窗⼝的消息处理函数(这个处理函数是DefWindowProc,这是很直觉的想法,⽽且传统的SDK程序确实是这样的,但是MFC程序⽐传统的SDK多了document/view,如果如果某个消息是做⽂档处理,那么就让这个消息直接流到document中去不是更好吗?所以才有了MFC命令传递机制、MFC消息映射的出现),但是为什么都统⼀到了AfxWndProc这⾥呢?这⾥⽤到了钩⼦技术。
下面几节将分析MFC的消息机制的实现原理和消息处理的过程。
为此,首先要分析ClassWizard实现消息映射的内幕,然后讨论MFC 的窗口过程,分析MFC窗口过程是如何实现消息处理的。
1.消息映射的定义和实现1.MFC处理的三类消息根据处理函数和处理过程的不同,MFC主要处理三类消息:∙Windows消息,前缀以“WM_”打头,WM_COMMAND例外。
Windows消息直接送给MFC窗口过程处理,窗口过程调用对应的消息处理函数。
一般,由窗口对象来处理这类消息,也就是说,这类消息处理函数一般是MFC窗口类的成员函数。
∙控制通知消息,是控制子窗口送给父窗口的WM_COMMAND通知消息。
窗口过程调用对应的消息处理函数。
一般,由窗口对象来处理这类消息,也就是说,这类消息处理函数一般是MFC 窗口类的成员函数。
需要指出的是,Win32使用新的WM_NOFITY来处理复杂的通知消息。
WM_COMMAND类型的通知消息仅仅能传递一个控制窗口句柄(lparam)、控制窗ID和通知代码(wparam)。
WM_NOTIFY能传递任意复杂的信息。
∙命令消息,这是来自菜单、工具条按钮、加速键等用户接口对象的WM_COMMAND通知消息,属于应用程序自己定义的消息。
通过消息映射机制,MFC框架把命令按一定的路径分发给多种类型的对象(具备消息处理能力)处理,如文档、窗口、应用程序、文档模板等对象。
能处理消息映射的类必须从CCmdTarget类派生。
在讨论了消息的分类之后,应该是讨论各类消息如何处理的时候了。
但是,要知道怎么处理消息,首先要知道如何映射消息。
1.MFC消息映射的实现方法MFC使用ClassWizard帮助实现消息映射,它在源码中添加一些消息映射的内容,并声明和实现消息处理函数。
现在来分析这些被添加的内容。
在类的定义(头文件)里,它增加了消息处理函数声明,并添加一行声明消息映射的宏DECLARE_MESSAGE_MAP。
消息映射的实现Windows消息概述Windows应用程序的输入由Windows系统以消息的形式发送给应用程序的窗口。
这些窗口通过窗口过程来接收和处理消息,然后把控制返还给Windows。
消息的分类队列消息和非队列消息从消息的发送途径上看,消息分两种:队列消息和非队列消息。
队列消息送到系统消息队列,然后到线程消息队列;非队列消息直接送给目的窗口过程。
这里,对消息队列阐述如下:Windows维护一个系统消息队列(System message queue),每个GUI线程有一个线程消息队列(Thread message queue)。
鼠标、键盘事件由鼠标或键盘驱动程序转换成输入消息并把消息放进系统消息队列,例如WM_MOUSEMOVE、WM_LBUTTONUP、WM_KEYDOWN、WM_CHAR等等。
Windows 每次从系统消息队列移走一个消息,确定它是送给哪个窗口的和这个窗口是由哪个线程创建的,然后,把它放进窗口创建线程的线程消息队列。
线程消息队列接收送给该线程所创建窗口的消息。
线程从消息队列取出消息,通过Windows把它送给适当的窗口过程来处理。
除了键盘、鼠标消息以外,队列消息还有WM_PAINT、WM_TIMER和WM_QUIT。
这些队列消息以外的绝大多数消息是非队列消息。
系统消息和应用程序消息从消息的来源来看,可以分为:系统定义的消息和应用程序定义的消息。
系统消息ID的范围是从0到WM_USER-1,或0X80000到0XBFFFF;应用程序消息从WM_USER(0X0400)到0X7FFF,或0XC000到0XFFFF;WM_USER到0X7FFF范围的消息由应用程序自己使用;0XC000到0XFFFF范围的消息用来和其他应用程序通信,为了ID的唯一性,使用::RegisterWindowMessage来得到该范围的消息ID。
消息结构和消息处理消息的结构为了从消息队列获取消息信息,需要使用MSG结构。
例如,::GetMessage函数(从消息队列得到消息并从队列中移走)和::PeekMessage函数(从消息队列得到消息但是可以不移走)都使用了该结构来保存获得的消息信息。
MSG结构的定义如下:typedef struct tagMSG { // msgHWND hwnd;UINT message;WPARAM wParam;LPARAM lParam;DWORD time;POINT pt;} MSG;该结构包括了六个成员,用来描述消息的有关属性:接收消息的窗口句柄、消息标识(ID)、第一个消息参数、第二个消息参数、消息产生的时间、消息产生时鼠标的位置。
应用程序通过窗口过程来处理消息如前所述,每个“窗口类”都要登记一个如下形式的窗口过程:LRESULT CALLBACK MainWndProc (HWND hwnd,// 窗口句柄UINT msg,// 消息标识WPARAM wParam,//消息参数1LPARAM lParam//消息参数2)应用程序通过窗口过程来处理消息:非队列消息由Windows直接送给目的窗口的窗口过程,队列消息由::DispatchMessage等派发给目的窗口的窗口过程。
窗口过程被调用时,接受四个参数:a window handle(窗口句柄);a message identifier(消息标识);two 32-bit values called message parameters(两个32位的消息参数);需要的话,窗口过程用::GetMessageTime获取消息产生的时间,用::GetMessagePos获取消息产生时鼠标光标所在的位置。
在窗口过程里,用switch/case分支处理语句来识别和处理消息。
应用程序通过消息循环来获得对消息的处理每个GDI应用程序在主窗口创建之后,都会进入消息循环,接受用户输入、解释和处理消息。
消息循环的结构如下:while (GetMessage(&msg, (HWND) NULL, 0, 0)) {//从消息队列得到消息if (hwndDlgModeless == (HWND) NULL ||!IsDialogMessage(hwndDlgModeless, &msg) &&!TranslateAccelerator(hwndMain, haccel, &msg)) {TranslateMessage(&msg);DispatchMessage(&msg); //发送消息}}消息循环从消息队列中得到消息,如果不是快捷键消息或者对话框消息,就进行消息转换和派发,让目的窗口的窗口过程来处理。
当得到消息WM_QUIT,或者::GetMessage出错时,退出消息循环。
MFC消息处理使用MFC框架编程时,消息发送和处理的本质也如上所述。
但是,有一点需要强调的是,所有的MFC窗口都使用同一窗口过程,程序员不必去设计和实现自己的窗口过程,而是通过MFC提供的一套消息映射机制来处理消息。
因此,MFC简化了程序员编程时处理消息的复杂性。
所谓消息映射,简单地讲,就是让程序员指定要某个MFC类(有消息处理能力的类)处理某个消息。
MFC提供了工具ClassWizard来帮助实现消息映射,在处理消息的类中添加一些有关消息映射的内容和处理消息的成员函数。
程序员将完成消息处理函数,实现所希望的消息处理能力。
如果派生类要覆盖基类的消息处理函数,就用ClassWizard在派生类中添加一个消息映射条目,用同样的原型定义一个函数,然后实现该函数。
这个函数覆盖派生类的任何基类的同名处理函数。
下面几节将分析MFC的消息机制的实现原理和消息处理的过程。
为此,首先要分析ClassWizard实现消息映射的内幕,然后讨论MFC的窗口过程,分析MFC窗口过程是如何实现消息处理的。
消息映射的定义和实现MFC处理的三类消息根据处理函数和处理过程的不同,MFC主要处理三类消息:Windows消息,前缀以“WM_”打头,WM_COMMAND例外。
Windows消息直接送给MFC 窗口过程处理,窗口过程调用对应的消息处理函数。
一般,由窗口对象来处理这类消息,也就是说,这类消息处理函数一般是MFC窗口类的成员函数。
控制通知消息,是控制子窗口送给父窗口的WM_COMMAND通知消息。
窗口过程调用对应的消息处理函数。
一般,由窗口对象来处理这类消息,也就是说,这类消息处理函数一般是MFC窗口类的成员函数。
需要指出的是,Win32使用新的WM_NOFITY来处理复杂的通知消息。
WM_COMMAND 类型的通知消息仅仅能传递一个控制窗口句柄(lparam)、控制窗ID和通知代码(wparam)。
WM_NOTIFY能传递任意复杂的信息。
命令消息,这是来自菜单、工具条按钮、加速键等用户接口对象的WM_COMMAND通知消息,属于应用程序自己定义的消息。
通过消息映射机制,MFC框架把命令按一定的路径分发给多种类型的对象(具备消息处理能力)处理,如文档、窗口、应用程序、文档模板等对象。
能处理消息映射的类必须从CCmdTarget类派生。
在讨论了消息的分类之后,应该是讨论各类消息如何处理的时候了。
但是,要知道怎么处理消息,首先要知道如何映射消息。
MFC消息映射的实现方法MFC使用ClassWizard帮助实现消息映射,它在源码中添加一些消息映射的内容,并声明和实现消息处理函数。
现在来分析这些被添加的内容。
在类的定义(头文件)里,它增加了消息处理函数声明,并添加一行声明消息映射的宏DECLARE_MESSAGE_MAP。
在类的实现(实现文件)里,实现消息处理函数,并使用IMPLEMENT_MESSAGE_MAP 宏实现消息映射。
一般情况下,这些声明和实现是由MFC的ClassWizard自动来维护的。
看一个例子:在AppWizard产生的应用程序类的源码中,应用程序类的定义(头文件)包含了类似如下的代码://{{AFX_MSG(CTttApp)afx_msg void OnAppAbout();//}}AFX_MSGDECLARE_MESSAGE_MAP()应用程序类的实现文件中包含了类似如下的代码:BEGIN_MESSAGE_MAP(CTApp, CWinApp)//{{AFX_MSG_MAP(CTttApp)ON_COMMAND(ID_APP_ABOUT, OnAppAbout)//}}AFX_MSG_MAPEND_MESSAGE_MAP()头文件里是消息映射和消息处理函数的声明,实现文件里是消息映射的实现和消息处理函数的实现。
它表示让应用程序对象处理命令消息ID_APP_ABOUT,消息处理函数是OnAppAbout。
为什么这样做之后就完成了一个消息映射?这些声明和实现到底作了些什么呢?接着,将讨论这些问题。
在声明与实现的内部DECLARE_MESSAGE_MAP宏:首先,看DECLARE_MESSAGE_MAP宏的内容:#ifdef _AFXDLL#define DECLARE_MESSAGE_MAP() \private: \static const AFX_MSGMAP_ENTRY _messageEntries[]; \protected: \static AFX_DA TA const AFX_MSGMAP messageMap; \static const AFX_MSGMAP* PASCAL _GetBaseMessageMap(); \virtual const AFX_MSGMAP* GetMessageMap() const; \#else#define DECLARE_MESSAGE_MAP() \private: \static const AFX_MSGMAP_ENTRY _messageEntries[]; \protected: \static AFX_DA TA const AFX_MSGMAP messageMap; \virtual const AFX_MSGMAP* GetMessageMap() const; \#endifDECLARE_MESSAGE_MAP定义了两个版本,分别用于静态或者动态链接到MFC DLL的情形。
BEGIN_MESSAE_MAP宏然后,看BEGIN_MESSAE_MAP宏的内容:#ifdef _AFXDLL#define BEGIN_MESSAGE_MAP(theClass, baseClass) \const AFX_MSGMAP* PASCAL theClass::_GetBaseMessageMap() \{ return &baseClass::messageMap; } \const AFX_MSGMAP* theClass::GetMessageMap() const \{ return &theClass::messageMap; } \AFX_DA TADEF const AFX_MSGMAP theClass::messageMap = \{ &theClass::_GetBaseMessageMap, &theClass::_messageEntries[0] }; \const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = \{ \#else#define BEGIN_MESSAGE_MAP(theClass, baseClass) \const AFX_MSGMAP* theClass::GetMessageMap() const \{ return &theClass::messageMap; } \AFX_DA TADEF const AFX_MSGMAP theClass::messageMap = \{ &baseClass::messageMap, &theClass::_messageEntries[0] }; \const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = \{ \#endif#define END_MESSAGE_MAP() \{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } \}; \对应地,BEGIN_MESSAGE_MAP定义了两个版本,分别用于静态或者动态链接到MFC DLL 的情形。