MFC中的消息映射宏 - magicyang87的专栏 - CSDN博客

来源:百度文库 编辑:神马文学网 时间:2024/04/30 13:40:55

MFC中的消息映射宏是用一系列的宏实现的,声明使用的MESSAGE_MAP_DECLARE (),开始部分用MESSAGE_MAP_BEGIN (),结束部分用MESSAGE_MAP_END (),中间的映射用MESSAGE (*,*)来实现.
        以前我一直搞不明白,说实话还是沉不下心来研究其中宏的具体含义.候捷的讲的很详细,其中还有对MFC的简易模拟实现,不过还是直到昨天看了段源码才真正明白了其中原理.

        首先,MFC的消息映射采用的数据结构就是一个二维数组

typedef struct _MSGMAP_ENTRY
{
UINT nMessage;           //消息ID
void (Wnd::*pfn)();        //函数指针
}MSGMAP_ENTRY;

        然后呢就可以声明一个MSGMAP_ENTRY类型的成员变量MSGMAP_ENTRY MessageEntry[];

其实这也就是MESSAGE_MAP_BEGIN的内容:

#define MESSAGE_MAP_BEGIN(ClassName) \
MSGMAP_ENTRY Wnd::MessageEntry[] = \
{

       很明显下面就是要为数组赋值

#define MESSAGE(MSG, PEOC) \
{MSG, &PEOC},

MESSAGE(*,*)的作用就是在二维数组中添加一项

       结束时调用MESSAGE_MAP_END ()

#define MESSAGE_MAP_END() \
{0, 0} \
};

即以0项结束,即ID为0,指针为NULL的项.

        有了这个二维数组,只需要在消息循环的处理函数中

int count = 0;
   while((MessageEntry[count].pfn) != 0)
   {
    if(MessageEntry[count].nMessage == nMsg)
    {
     (this->*MessageEntry[count].pfn)();
     return 0;
    }
    count++;
   }

即实现了消息映射,即对于特定ID调用相应的函数.

        现在似乎不提倡使用宏,说会让代码不直观,而且增加调试难度.确实是这样,不过宏的优势是显而易见的.假如上面的功能不用宏,就需要在所有窗口类的基类中为所有的消息构造虚拟函数,性能肯定可以和JAVA比一下了,而宏则对性能无任何影响,这应该也是MFC中采用宏,而非用所谓"面向对象"来设计的原因.

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/magicyang87/archive/2008/01/28/2069212.aspx