当前位置:C++技术网 > 资讯 > 深入图解MFC消息映射,让你一目了然

深入图解MFC消息映射,让你一目了然

更新时间:2015-06-26 19:56:41浏览次数:1+次

    先上图,下面对照图片来认真阅读,以便可以更清晰的理解。

MFC消息映射图解

    在VC6.0或者VS系列IDE中,添加一个事件响应是非常轻松便捷的事情。因为有向导的存在,省掉了很多麻烦事。然而,我们依然非常有必要深入了解MFC的事件响应机制。这里采用图解的形式,让描述更加清晰。
    从我们最熟悉的部分开始,以菜单为例,其他的类推。
    在我们添加一个菜单,给菜单添加事件后,向导自动生成一系列代码,完成事件响应。一共有三处,一个在头文件,两个在源文件(CPP文件)。就是图中右边所显示的内容。
    在头文件中,有一个消息映射声明宏DECLARE_MESSAGE_MAP(),它看起来像一个函数,实际上就是一个宏而已。它展开后就如箭头指向的方框中的样子。宏展开的内容的含义,在后面讨论。
    在源文件(图中标注的实现文件)中,有两个部分。第一个是消息映射实现宏,第二个是响应函数的实现。函数实现与普通的成员函数一样,不用多说。
    以上就是向导为我们生成的东西。而这些东西的内部运作机制如何,我们下面详细讨论。
    消息映射宏展开后的代码中,第一个是私有的静态数组_messageEntries,正如左边中间的图显示的那样,这里是存储消息处映射的条目的数组。第二个是静态的消息映射图的一个结构体messageMap,messageMap第一个成员是指向父类的消息映射数组的指针,用于向上回溯消息处理。messageMap第二个成员指向自己的消息映射数组。而这个父类,由BEGIN_MESSAGE_MAP中的第二个参数指定。消息映射宏展开后的代码中的第三个是一个函数GetMessageMap,用于获取指向消息映射messageMap的指针。
    在消息映射中的ON_COMMAND的命令处理的条目,以及各种标准消息,都会记录到_messageEntries中。对应的关系如图中箭头所示。数组中第一个是消息的标识如ON_COMMAND,WM_PAINT等。对于ON_COMMAND是有参数的,这些参数用于确定控件的控件ID和处理的函数。控件ID和处理函数都会存入数组中的对应的位置。而已WM_开头的非命令的标准消息,则都有标准的处理函数,也就不需要我们提供处理函数。
    消息在响应时,首先是在消息映射数组_messageEntries中查找,如果找到了触发的菜单或控件事件,就会在_messageEntries中查找是否有对应的消息处理条目,如果有,则调用条目中记录的函数。如果没有则获取消息映射messageMap的地址,然后获取父类的(或者说是上一级)地址,然后通过这个地址,找到对应的消息映射数组,在数组中查找是否有消息处理条目。如果有则调用条目中记录的函数,没有则继续向上一级查找,知道最后的windows的默认处理过程结束。
    以上的处理过程,也就是MFC的命令路由的大致过程,这里只是简单的深入讨论一下,并不是很全面。但是可以加深你对MFC的消息处理的理解。如果想了解更全面的机制讲解,请阅读《深入浅出MFC》,此电子书在本网站可以下载。
    鉴于本人水平有限,如果错误或者不准确的地方,请指正。