MFC 메시지 매핑

6677 단어
MFC에서 메시지 응답 함수는 프로그램에서 세 가지 관련 부분이 있는데 하나는 헤더 파일의 메시지 함수에 대한 성명이다.둘째는 cpp 파일의 메시지 매크로입니다.세 번째는 cpp 파일의 메시지 함수의 함수체입니다.
1 지금view 파일로 말하자면 h 파일에는 다음과 같은 정보가 포함되어 있다.
protected:
         afx_msg voidOnFilePrintPreview();
         afx_msg voidOnRButtonUp(UINT nFlags, CPoint point);
         afx_msg voidOnContextMenu(CWnd* pWnd, CPoint point);
         DECLARE_MESSAGE_MAP()
public:
         afx_msg intOnCreate(LPCREATESTRUCT lpCreateStruct);
         afx_msg voidOnFileNew();

cpp에는 다음이 포함됩니다.
BEGIN_MESSAGE_MAP(Cmfcstd11View,CView)
         //       
         ON_COMMAND(ID_FILE_PRINT,&CView::OnFilePrint)
         ON_COMMAND(ID_FILE_PRINT_DIRECT,&CView::OnFilePrint)
         ON_COMMAND(ID_FILE_PRINT_PREVIEW,&Cmfcstd11View::OnFilePrintPreview)
         ON_WM_CONTEXTMENU()
         ON_WM_RBUTTONUP()
         ON_WM_CREATE()
         ON_COMMAND(ID_FILE_NEW,&Cmfcstd11View::OnFileNew)
END_MESSAGE_MAP()

함수 구현:
//             ,    
int Cmfcstd11View::OnCreate(LPCREATESTRUCTlpCreateStruct)
{
         if(CView::OnCreate(lpCreateStruct) == -1)
                   return-1;
         // TODO:              
                   return0;
}
void Cmfcstd11View::OnFileNew()
{
         // TODO:                  
         ::MessageBox(NULL,TEXT("OK"),TEXT("THis"),MB_OK);
}

2 이제 매크로를 펼칩니다.
#define DECLARE_MESSAGE_MAP() \
protected: \
         static const AFX_MSGMAP* PASCAL GetThisMessageMap(); \
         virtualconst AFX_MSGMAP* GetMessageMap() const; \

매크로 줄 연결부호를 제거하면 다음과 같은 것을 볼 수 있습니다.
protected:
         static const AFX_MSGMAP* PASCAL GetThisMessageMap();
         virtualconst AFX_MSGMAP* GetMessageMap() const;

사실은 클래스에서 두 개의 함수를 정의한 것이다. 함수가 어떤 의미에 관해서는 우리는 우선 상관하지 않고 이어서 아래를 본다
#define BEGIN_MESSAGE_MAP(theClass, baseClass) \
         PTM_WARNING_DISABLE \
         constAFX_MSGMAP* theClass::GetMessageMap() const \
                   { returnGetThisMessageMap(); } \
         constAFX_MSGMAP* PASCAL theClass::GetThisMessageMap() \
         { \
                   typedeftheClass ThisClass;                                                        \
                   typedefbaseClass TheBaseClass;                                             \
                   staticconst AFX_MSGMAP_ENTRY _messageEntries[] =  \
                   {
#define ON_COMMAND(id, memberFxn) \
         { WM_COMMAND, CN_COMMAND, (WORD)id,(WORD)id, AfxSigCmd_v, \
                   static_cast<AFX_PMSG>(memberFxn) },
 
#define END_MESSAGE_MAP() \
                   {0, 0, 0, 0, AfxSig_end,(AFX_PMSG)0 } \
         }; \
                   staticconst AFX_MSGMAP messageMap = \
                   {&TheBaseClass::GetThisMessageMap, &_messageEntries[0] }; \
                   return&messageMap; \
         }                                                                           \
         PTM_WARNING_RESTORE

이거는 베인...MESSAGE_MAP 및 ENDMESSAGE_MAP의 매크로 정의는 매크로를 확장하여
__pragma(warning(push ))  __pragma(warning( disable : 4867))
         const AFX_MSGMAP*theClass::GetMessageMap() const
         {
                   return GetThisMessageMap();
         }
         const AFX_MSGMAP* PASCALtheClass::GetThisMessageMap()
         {
                   typedef theClass ThisClass;                                                       
                   typedef baseClassTheBaseClass;                                            
                   static const AFX_MSGMAP_ENTRY_messageEntries[] = 
                   {
                            { WM_COMMAND,CN_COMMAND, (WORD)id, (WORD)id, AfxSigCmd_v, static_cast<AFX_PMSG>(memberFxn) },
                            {0, 0, 0, 0,AfxSig_end, (AFX_PMSG)0 }
                   };
                   static const AFX_MSGMAPmessageMap =
                   {&TheBaseClass::GetThisMessageMap, &_messageEntries[0] };
                   return &messageMap;
         }                                                                        
__pragma(warning(pop ))
 
structAFX_MSGMAP_ENTRY;       // declared belowafter CWnd
struct AFX_MSGMAP
{
         const AFX_MSGMAP* (PASCAL*pfnGetBaseMap)();
         const AFX_MSGMAP_ENTRY* lpEntries;
};
 
structAFX_MSGMAP_ENTRY
{
         UINT nMessage;   // windows message
         UINT nCode;      // control code or WM_NOTIFY code
         UINT nID;        // control ID (or 0 for windowsmessages)
         UINT nLastID;    // used for entries specifying a range ofcontrol id's
         UINT_PTR nSig;       // signature type (action) or pointer tomessage #
         AFX_PMSG pfn;    // routine to call (or special value)
};
typedef void (AFX_MSG_CALLCCmdTarget::*AFX_PMSG)(void);

위의 매크로를 확장하면 각 클래스는 메시지 매핑과 관련된 두 가지 함수를 선언합니다.
protected:
         staticconst AFX_MSGMAP* PASCAL GetThisMessageMap();
         virtualconst AFX_MSGMAP* GetMessageMap() const;

여기서 정적 함수 GetThisMessageMap()에 클래스 자체에 대한 정적 메시지 배열이 정의됩니다.
static const AFX_MSGMAP_ENTRY _messageEntries[]
GetThisMessageMap() 함수는 구조체의 포인터를 반환합니다.
struct AFX_MSGMAP
{
         const AFX_MSGMAP* (PASCAL*pfnGetBaseMap)();
         const AFX_MSGMAP_ENTRY* lpEntries;
};

이 구조에서 볼 수 있듯이 이것은 부모 클래스의 메시지 데이터와 자신의 메시지 그룹을 포함하기 때문에 함수GetThisMessageMap()을 통해 클래스 자체와 부모 클래스의 메시지 응답 함수를 얻을 수 있다.
위에서 보듯이 이른바 메시지와 메시지 함수의 정적 대조표는 위에서 말한 GetThisMessage () 함수 중의static const AFXMSGMAP_ENTRY_메시지 Entries[] 정적 배열.
인손흠: MFC는 백그라운드에서 하나의 창 손잡이와 대응하는 C++ 대상 지침의 대조표를 유지한다. 창 손잡이와 대상 지침은 일일이 대응하는 관계이다. 어떤 소식을 받았을 때 메시지의 첫 번째 파라미터는 이 소식이 어느 창 손잡이와 관련이 있는지 가리키고 대조표를 통해 이와 관련된 지침을 찾을 수 있다.그리고 이 바늘을 프로그램 프레임워크 창 클래스의 기본 클래스에 전달하고, 후자는 윈도 Proc라는 함수를 호출합니다.이 함수 정의는 WindCore에 있습니다.cpp 파일.
LRESULTCWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
         // OnWndMsgdoes most of the work, except for DefWindowProc call
         LRESULT lResult = 0;
         if(!OnWndMsg(message, wParam, lParam, &lResult))
                   lResult = DefWindowProc(message,wParam, lParam);
         returnlResult;
}

OnWndMsg 프로세스는 다음과 같습니다.
우선 메시지에 메시지 응답 함수가 있는지 판단합니다.
판단 방법은 상응하는 창 클래스에서 필요한 메시지 응답 함수를 찾는 것입니다.윈도 Proc에 전달되는 것은 창의 하위 클래스 포인터이기 때문에 OnWndMsg는 해당하는 하위 클래스 헤더 파일에서 메시지 응답 함수 설명이 있는지 확인합니다.하위 클래스의 소스 파일로 이동하여 BEGIN 을 봅니다.MESSAGE_MAP 및 ENDMESSAGE_MAP, 두 매크로 사이에 적절한 메시지 매크로가 있는지 여부.
메시지 응답 함수를 찾으면 이 함수를 호출합니다. 그렇지 않으면 기본 클래스에 맡깁니다.

좋은 웹페이지 즐겨찾기