MFC消息映射机制(2)
来源:互联网 发布:手机实用小五金软件 编辑:程序博客网 时间:2024/06/06 06:52
说起MFC的消息映射机制,刚开始学的时候可能觉得很神奇,怎么通过3个宏就可以实现整个程序的消息循环。其实你将宏展开便会有所发现,这些宏就是在类里面定义了一些成员变量和成员函数,然后通过类外的宏将其实现。然后通过面向对象的相关性质,在库函数中进行实现。下面我们分开来说明下。
先来认识两个重要的数据结构:
Struct AFX_MSGMAP_ENTRY{
UINT nMessage; //消息ID
UINT nCode; //通知码
UINT nID; //命令ID/控件ID
UINT nLastID; //最后一个控件ID
UINT nSig; //消息处理函数类型
AFX_PMSG pfn; //消息处理函数的地址(指针)
};
Struct AFX_MSGMAP{
CONST AFX_MSGMAP *pBaseMap;
CONST AFX_MSGMAP_ENTRY* lpEntries;
};
消息映射的实现这两个数据结构起到了相当重要的作用。首先类里面定义了一个静态AFX_MSGMAP类型的成员变量,通过上面我们可以看出这个结构中有两个成员,一个是相同类型的变量地址,一个是AFX_MSGMAP_ENTRY类型的地址。然而通过类外的实现宏赋值。我们可以清楚的看到,前者是父类的静态变量的地址。后者是本类静态数组的地址。而静态数组的每一项便是上面的结构体一,{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 }这是这个结构的结尾,于是我们可以猜测,在MFC库中肯定进行了某种搜索,以上面写出的那项作为结束标志。
学过C语言的链表应该都是很清楚的,通过自己的next域找到下一个结点。这个的AFX_MSGMAP中有保存父类同类型的地址,会不会其实也像链表一样,可以让我们一直遍历这条继承链呢,其实MFC就是这样做的。那么怎么获取链表的头节点呢,我们的宏展开后还有一个函数成员函数GetMessageMap,就是这个函数返回了我们类中的静态成员变量AFX_MSGMAP对象的地址。到这里我们便得到了这个链的头结点。最后说明一点,你在BEGIN_MESSAGE_MAP和END_MESSAGE_MAP宏之间添加的消息宏便是添加了lpEntries这个数组中的项。
现在我们来看看消息处理的过程:
当一个消息产生的时候...
1、首先利用GetMessageMap获取本类静态变量的地址(链表头结点)pMessageMap。
2、利用pMessageMap的第二个参数获取本类静态数组的地址,然后在数组中查找消息对应的处理函数,如果找到了执行3,没找到执行4.
3、使用找到的数组元素的最后一个成员(成员函数的地址),并且调用这个函数完成消息的处理。(如果自己类中没有实现这个函数,便会调用父类同名函数)
4、利用pMessageMap的第一个元素获取父类的静态变量地址,并重新给pMessageMap赋值为父类的静态变量地址执行2
5、如果遍历整个链表还是没有找到,调用DefWndProc对消息做默认处理!
最后值得一提的是MFC的消息分类:
1.window的标准消息 ON_WM_XXX 例如:ON_WM_CREATE()
2.命令消息(WM_COMMAND)(也是Window标准消息因为比较特殊分开来写)
i. ON_COMMAND(命令ID,处理函数)
ii. ON_COMMAND_RANGE(起始ID,终止ID,处理函数)
这里的处理函数需要自己地址,类型可以再MSDN中查询
3自定义消息
#define WM_MYMESSAGE WM_USER+n;
添加宏ON_MESSAGE(消息ID,处理函数)
注意这里的WM_USER是一个宏,表示自定义消息的起点
4通知消息(ON_通知码) 例如: ON_EN_CHANGE
- MFC消息映射机制(2)
- Thinking in MFC---消息机制2(消息映射)
- MFC消息映射机制
- MFC消息映射机制
- MFC消息映射机制
- MFC消息映射机制
- MFC消息映射机制
- MFC消息映射机制
- MFC消息映射机制
- MFC消息映射机制
- MFC消息映射机制
- MFC 消息映射机制
- MFC消息映射机制
- MFC消息映射机制
- MFC消息映射机制
- MFC消息映射机制
- MFC消息映射机制
- MFC消息映射机制
- OSG和osgearth显示中文
- Android 高级动画总结(Property Animation)
- java中length属性,length()方法和size()的方法的区别
- 3.11 如何让app使用icon fonts
- ScrollView好用技巧
- MFC消息映射机制(2)
- Git/Repo related cmds
- Linux下的packet socket使用总结
- UI控件看不见或不能点击原因总结
- HDU2066
- 使用 Spring 3 MVC HttpMessageConverter 功能构建 RESTful web 服务
- C++中的双冒号作用
- 从B树、B+树、B*树谈到R 树
- HUAWEI 路由器vlanif vlan间路由