從MFC訊息映射宏分析MFC訊息映射的實現

來源:互聯網
上載者:User

 

在MFC中,我們可以找到如下三個宏

DECLARE_MASSAGE_MAP()

BEGINE_MASSAGE_MAP(CLASS, BASSCLASS)

END_MASSAGE_MAP()

 

下面來分析這三個宏

1  DECLARE_MESSAGE_MAP() 

作用:為一個訊息響應類聲明必需的成員變數和成員函數。

#define DECLARE_MESSAGE_MAP() 

private: 

     static const AFX_MSGMAP_ENTRY _messageEntries[]; 

protected: 

     static const AFX_MSGMAP messageMap; 

     virtual const AFX_MSGMAP* GetMessageMap() const; 

可以看出DECLARE_MESSAGE_MAP() 宏中定義了兩個靜態成員函數和一個重載的虛函數

AFX_MSGMAP_ENTRY 根據題意,可以看出這是一個訊息入口(訊息和訊息函數之間的映射)

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)
}; 再看看AFX_MESSAGE結構

struct AFX_MSGMAP
{
     const AFX_MSGMAP* pBaseMap;
     const AFX_MSGMAP_ENTRY* lpEntries;
};可見結構體AFX_MSGMAP中定義了兩個指標,pBaseMap指向另一個AFX_MSGMAP,lpEntries指向一個訊息入口表。可以推想,在響應訊息時,一定是在lpEntries指向的訊息入口表中尋找響應函數,也可能會在pBaseMap指向的結構體中做同樣的響應函數尋找操作(有點不理解)。重載的虛函數GetMessageMap,可以猜測只是用來返回成員messageMap的地址而已 2 BEGIN_MESSGAE_MAP(CLASS, BASECLASS)

作用:定義DECLARE_MESSAGE_MAP宏聲明的靜態變數。#define BEGIN_MESSAGE_MAP(theClass, baseClass) 
     const AFX_MSGMAP* theClass::GetMessageMap() const 
         { return &theClass::messageMap; } 
     AFX_COMDAT const AFX_MSGMAP theClass::messageMap = 
     { &baseClass::messageMap, &theClass::_messageEntries[0] }; 
     AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = 
     { 


BEGIN_MESSAGE_MAP宏有兩個參數,theClass表示為當前類,bassClass為當前類的父類。

BEGIN_MESSAGE_MAP宏首先定義了函數GetMessageMap的函數體,如前文所述,直接返回當前類的成員變數messageMap的地址。

const AFX_MSGMAP* theClass::GetMessageMap() const 
         { return &theClass::messageMap; } 

然後初始化了當前類的成員變數messageMap。messageMap的pBaseMap指標指向其父類的messageMap成員,lpEntries指標指向當前類的_messageEntries數組的首地址。AFX_COMDAT const AFX_MSGMAP theClass::messageMap = 
     { &baseClass::messageMap, &theClass::_messageEntries[0] };最後,定義了_messageEntries數組初始化代碼的開始部分。    AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = 
     {  第三個宏END_MESSAGE_MAP()作用:定義_messageEntries數組初始化代碼的結束部分。#define END_MESSAGE_MAP() 
         {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } 
     }; 
在DECLARE_MESSAGE_MAP和END_MESSAGE_MAP之間還有一些宏,如ON_COMMAND、ON_WM_CREATE等,這些宏最終都會被產生一條AFX_MSGMAP_ENTRY結構體資料,並成為_messageEntries訊息映射表資料的一個元素。我們以常見的ON_COMMAND宏為例。ON_COMMAND宏的原始碼為:#define ON_COMMAND(id, memberFxn) 
     { WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)id, AfxSigCmd_v, 
         static_cast<AFX_PMSG> (memberFxn) },通過以上分析,我們可以得到一個鏈表式的資料結構,子類的messageMap成員為鏈表的前端節點。鏈表的每個節點都包含一個訊息入口表。MFC的訊息系統的標準備訊息處理函數CCmdTarget::OnCmdMsg正是通過這樣一個鏈表尋找到訊息的響應函數,並調用該函數來響應訊息。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.