MFC的MESSAGE MAP宏

本文解析了MFC中消息映射机制的工作原理,详细介绍了DECLARE_MESSAGE_MAP(), BEGIN_MESSAGE_MAP() 和 END_MESSAGE_MAP() 宏的使用方法及背后的实现逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文链接:http://kwun.blogbus.com/logs/4272601.html


用惯了MFC的自动代码生成模版, 就不会去管这些东西. 不过有时候看到那个奇怪的定义, 还是会奇怪唔, 怎么工作的?

今天看了一下源代码, 大概了解了一下. 嗯, 一起来看看. 首先是类声明中用到的 DECLARE_MESSAGE_MAP():

#define DECLARE_MESSAGE_MAP()                            \
protected:                                               \
    static const AFX_MSGMAP* PASCAL GetThisMessageMap(); \
    virtual const AFX_MSGMAP* GetMessageMap() const;     \

这个宏很直观了, 声明了两个函数. 注意GetMessageMap()是一个虚函数. 这两个函数在后面的定义中会用到.

其次是.CPP中的BEGIN_MESSAGE_MAPEND_MESSAGE_MAP:

#define BEGIN_MESSAGE_MAP(theClass, baseClass)             \
    PTM_WARNING_DISABLE                                    \
    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;                                \
    }                                                      \
    PTM_WARNING_RESTORE

好像比较抽象的样子. 其实展开来看就清楚了, 以ON_WM_SIZE()为例

BEGIN_MESSAGE_MAP(CCrossbowTestDlg, CDialog)
    ON_WM_SIZE()
END_MESSAGE_MAP()

展开并精简之后得到如下形式:

const AFX_MSGMAP* CTestDialog::GetMessageMap() const
{
    return GetThisMessageMap();
}

const AFX_MSGMAP* PASCAL CTestDialog::GetThisMessageMap()
{
    static const AFX_MSGMAP_ENTRY _messageEntries[] =
    {
        {WM_SIZE, 0, 0, 0, AfxSig_vwii, &CTestDialog::OnSize},
        {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0}
    };

    static const AFX_MSGMAP messageMap =
    {&CDialog::GetThisMessageMap, &_messageEntries[0]};
    return &messageMap;
}

具体的函数使用流程还没有去看, 不过看这个定义以及逻辑上的处理结果, 应该是: 当一个消息被解析时, 对于GetMessageMap()中(通过GetThisMessageMap())返回的messageMap, 首先检测_messageEntries中是否有匹配的消息响应函数(通过MESSAGE ID), 若有则执行相应函数, 否则(_messageEntries检测到达最末一个成员, 其MESSAGE ID为0)通过调用基类的GetThisMessageMap()获得基类的messageMap, 并重复上述动作, 直到消息被解析为止.



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值