한 걸음씩..

[MFC] MessageMap 매크로 함수 풀이 본문

프로그래밍

[MFC] MessageMap 매크로 함수 풀이

반엘 2013. 10. 2. 09:30

       MessageMap 매크로 함수


#define DECLARE_MESSAGE_MAP() 

private: 

    static const AFX_MSGMAP_ENTRY _messageEntries[]; // 메시지 배열 변수 생성

protected: 

    static AFX_DATA const AFX_MSGMAP messageMap; // 메시지 맵 생성

    static const AFX_MSGMAP* PASCAL _GetBaseMessageMap(); 

    virtual const AFX_MSGMAP* GetMessageMap() const;


    const AFX_MSGMAP* PASCAL CMainWindow::_GetBaseMessageMap() 

    { 

        return &CFrameWnd::messageMap;  //부모 메시지 맵 주소를 넘겨줌

    } 


    const AFX_MSGMAP* CMainWindow::GetMessageMap() const 

    { 

        return &CMainWindow::messageMap;  //자신의 메시지 맵 주소를 넘겨줌

    } 


    AFX_COMDAT AFX_DATADEF const AFX_MSGMAP CMainWindow::messageMap =       

    { &CMainWindow::_GetBaseMessageMap, &CMainWindow::_messageEntries[0]  };  //메시지맵 첫번째 배열에 자신의 주소를 넣어줌


    AFX_COMDAT const AFX_MSGMAP_ENTRY CMainWindows::_messageEntries[] =

    { 

         { WM_PAINT, 0, 0, 0, AfxSig_vv, (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(void))&OnPaint  } 

         { WM_CREATE, 0, 0, 0, AfxSig_is, (AFX_PMSG)(AFX_PMSGW)(int (AFX_MSG_CALL CWnd::*)(LPCREATESTRUCT))&OnCreate } 

         { 0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } 

    }; 



       MessageMap 사용 구조체


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)(); // pfnGetBaseMap : 부모 클래스의 메시지 맵의 주소가 저장. 부모가 없으면 NULL

    const AFX_MSGMAP_ENTRY* lpEntries;  // lpEntries : 자기 클래스가 가지고 있는 MessageEntries의 0번째 주소

};



       MessageMap 시나리오


메시지 발생( WM_RBUTTONDOWN) -> 자식 Class Message Map 확인 -> CMyClass::OnRButtonDown() 호출 -> 발견하지 못햇다면 부모 Class Message Map 확인 -> 발견되었다면 CParentClass::OnRButtonDown() 호출 -> 발견하지 못했다면 CCmdTarget Class까지 올라가면서 메시지 핸들러 검색