长时间人容易遗忘,从新捡起!特做下记录

MFC消息映射

1.在MFC中消息映射主要牵扯到三个宏分别为:

DECLARE_MESSAGE_MAP()
BEGIN_MESSAGE_MAP(theClass, baseClass)
END_MESSAGE_MAP()

2.先看源码

#define DECLARE_MESSAGE_MAP() \
protected: \
static const AFX_MSGMAP* PASCAL GetThisMessageMap(); \
virtual const AFX_MSGMAP* GetMessageMap() const; \
#define BEGIN_MESSAGE_MAP(theClass, baseClass) \
const AFX_MSGMAP* theClass::GetMessageMap() const \
{ return GetThisMessageMap(); } \
const AFX_MSGMAP* PASCAL theClass::GetThisMessageMap() \
{ \
typedef theClass ThisClass; \
typedef baseClass TheBaseClass; \
static const AFX_MSGMAP_ENTRY _messageEntries[] = \
{
#define END_MESSAGE_MAP() \
{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } \
}; \
static const AFX_MSGMAP messageMap = \
{ &TheBaseClass::GetThisMessageMap, &_messageEntries[0] }; \
return &messageMap; \
}

3.上述源码中牵扯到两个结构体分别为

struct AFX_MSGMAP_ENTRY
{
UINT nMessage; // windows message
UINT nCode; // control code or WM_NOTIFY code
UINT nID; // control ID (or 0 for windows messages)
UINT nLastID; // used for entries specifying a range of control id's
UINT_PTR nSig; // signature type (action) or pointer to message #
AFX_PMSG pfn; // routine to call (or special value)
};
struct AFX_MSGMAP
{
const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
const AFX_MSGMAP_ENTRY* lpEntries;
};

包含两部分:1.函数指针(指向父类的获取AFX_MSGMAP的指针的静态函数)  2.AFX_MSGMAP_ENTRY结构体的指针

形成结构图

4.无论MFC中消息的走向如何(是向基类直接走还是横向走消息),我们先必须把整个爬行路线网建立起来,即如上图就可以把基类和派生类连接起来。

作为消息基类CCmdTarget需要特殊处理,即CCmdTarget的父类的AFX_MSGMAP为NULL,CCmdTarget内的AFX_MSGMAP_ENTRY仅包含一项,       如下:

CCmdTarget类头文件包含

DECLARE_MESSAGE_MAP()

CCmdTarget类源文件有

const AFX_MSGMAP* CCmdTarget::GetMessageMap() const
{
return GetThisMessageMap();
} const AFX_MSGMAP* CCmdTarget::GetThisMessageMap()
{
static const AFX_MSGMAP_ENTRY _messageEntries[] =
{
{ 0, 0, AfxSig_end, 0 } // nothing here
};
static const AFX_MSGMAP messageMap =
{
NULL,
&_messageEntries[0]
};
return &messageMap;
}

简化版本:

#ifndef __DEFINE_H__
#define __DEFINE_H__ typedef void (*CALL_MSG)(int wParam, int lParam); struct MSG_MAP_ENTRY
{
unsigned int nMessage; //消息类型
unsigned int nSig; // 信号类型
CALL_MSG pfn; //回调函数,即处理函数
}; struct MSG_MAP
{
MSG_MAP* (*pfnGetBaseMap)();
MSG_MAP_ENTRY* lpEntries;
}; #define DECLARE_MESSAGE_MAP() \
static const MSG_MAP* GetThisMessageMap(); \
virtual const MSG_MAP* GetMessageMap(); #define BEGIN_MESSAGE_MAP(theClass, baseClass) \
const MSG_MAP* theClass::GetMessageMap(){ \
return GetThisMessageMap(); \
} \
const MSG_MAP* theClass::GetThisMessageMap() \
{ \
typedef theClass ThisClass; \
typedef baseClass TheBaseClass; \
static const MSG_MAP_ENTRY _messageEntries[] = \
{ #define END_MESSAGE_MAP() \
{0, 0, (CALL_MSG)0 } \
}; \
static const AFX_MSGMAP messageMap = \
{ &TheBaseClass::GetThisMessageMap, &_messageEntries[0] }; \
return &messageMap; \
} #endif

最新文章

  1. HTML+CSS布局技巧及兼容问题【阅读季】
  2. C#中日期记忆日期的格式化,日期格式化说明
  3. 功能强大的web打印控件lodop的使用
  4. 大数据时代的IT架构设计
  5. RabbitMQ介绍6 - 其它
  6. [转]ionic $state.go passed $stateParams
  7. Apache2.2+Tomcat7.0整合配置详解
  8. 【转】ubuntu 编码 UTF-8 GBK GB18030
  9. C# 禁止 Webbrowser 控件的弹出脚本错误对话框
  10. 2015-09-22CSS:border、background、表格、超链接、overflow、firebug
  11. word页面不对齐,如何解决?
  12. Activity生命周期的学习以及Logcat的使用
  13. java final 和instanceof 关键字
  14. C++から広がり
  15. ASP.NET快速开发框架、这才是高大上档次后台管理UI界面
  16. SQL Server中TempDB管理(版本存储区的一个example)
  17. eclipse添加桌面快捷方式
  18. System.Data.Entity.Infrastructure.DbUpdateException
  19. emqx源码编译
  20. AOJ 0189 Convenient Location (Floyd)

热门文章

  1. java的HashSet 原理
  2. 思科SVI接口和路由接口区别
  3. CAT偶现NPE的问题
  4. HDU 1243 反恐训练营(最长公共序列)
  5. 《机器学习实战》中的程序清单2-1 k近邻算法(kNN)classify0都做了什么
  6. 计蒜客 31451 - Ka Chang - [DFS序+树状数组][2018ICPC沈阳网络预赛J题]
  7. 51nod 1126 - 求递推序列的第N项 - [找规律]
  8. 2018No-java面试知识
  9. (object) array
  10. Arctic Network---poj2349 最小生成树