MFC中的消息映射宏

MFC中的消息映射宏是用一系列的宏實現的,聲明使用的MESSAGE_MAP_DECLARE (),開始部分用MESSAGE_MAP_BEGIN (),結束部分用MESSAGE_MAP_END (),中間的映射用MESSAGE (*,*)來實現.

        以前我一直搞不明白,說實話還是沉不下心來研究其中宏的具體含義.候捷的<MFC深入淺出>講的很詳細,其中還有對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中採用宏,而非用所謂"面向對象"來設計的原因.

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章