본문 바로가기

API / MFC/Tip / Information

afx_msg이란?

#define afx_msg

로 정의되어 있어서 아무 의미가 없는 키워드 입니다.

그런데 왜 

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
이런식으로 표현이 되어 있을까요!?

간단하게 설명을 하게 되면,

afx_msg 키워드는 virtual과 같은 의미로 사용하는 것입니다.

하지만 왜 virtual을 사용하지 않고 afx_msg를 사용하는지를 보면

먼저 위 예로 적은

OnCreate의 함수를 보도록 하겠습니다.
class CWnd : public CCmdTarget
{
    ..........
    
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    
    ..........
};

이렇게 afxwin.h 파일에 정의가 되어 있습니다.

즉, 다시 설명하면

virtual로 선언이 안되어 있는 것이죠.

왜 virtual로 선언이 안되었을까요?

그것은 이런 메세지핸들러 함수가 200여개 정도 되기 때문입니다.

그래서 이런 메세지 핸들러 함수를 모두 가상함수로 선언하게 된다면

각각 함수마다 포인터가 필요하게 되는데 그렇게 하면,

포인터가 존재하는 메모리가 더 필요하게 되기 때문입니다.

그래서 가상함수로 선언을 하는 것은 메모리크기 문제로 인하여 사용하지 않았습니다.

그럼 다른 방법을 연구를 해야 되는데 그 방법이 일반 함수로 선언을 하되

메시지 맵이라는 새로운 방법을 이용을 하는 방법인데, 

BEGIN_MESSAGE_MAP(CMfc_appwizard_exe_single_docApp, CWinApp)
	//{{AFX_MSG_MAP(CMfc_appwizard_exe_single_docApp)
	ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
	// Standard file based document commands
	ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
	ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
	// Standard print setup command
	ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()

이런식으로 사용을 합니다.

그럼 컴파일러에서 이 메세지 맵에 있는 함수는 

실행하면서 오버라이딩 시킨 함수의 내용을 읽도록 하였습니다.

이렇게 메세지 핸들러 함수를 사용을 하는데,

그래서 virtual 키워드 대신 afx_msg 라는 키워드를 사용하여

사용자가 동적 오버라이딩 했다는 것을 알아 보기 쉽도록 키워드를 적었는 것입니다.