MFC

MFC 메시지 맵의 구현 원리

디버그정 2008. 8. 30. 20:08
MFC 메시지 맵의 구현 원리 | C/C++
전체공개 2006.04.01 23:01

 

MessageMap 구조체를 다음과 같이 만들 있다.

 

class CView;

typedef void (CView::*CViewFunPointer)();

typedef struct tagMessageMap

{

        UINT iMsg;

        CViewFunPointer fp;

} MessageMap;

 

구조체의 첫번째 멤버는 윈도우 메시지, 두번째 멤버는 CView 클래스의 멤보 함수의 시작 주소

 

static CViewFunPointer fpCViewGlobal;

 

CView 클래스에서 메시지 맵은 static으로 선언된다.

 

class CView : public CObject

{

public:

        static MessageMap messageMap[];

public:

        void OnCreate();

        void OnDraw();

        void OnDestroy();

};

 

클래스의 구현 파일에서 다음과 같이 초기화한다.

 

//{{BEGIN_MESSAGE_MAP

MessageMap CView::messageMap[]=

{

        {WM_CREATE,CView::OnCreate},

        {WM_PAINT,CView::OnDraw},

        {WM_DESTROY,CView::OnDestroy},

        {0,NULL}

};

//}}END_MESSAGE_MAP

 

{0,NULL} 탐색의 끝을 알리기 위해서 반드시 필요하다.

 

//Global object------------------------------------------------------

CView app;

 

윈도우 프로시저는 CView 선언된 정적 메시지 테이블을 검색하여 해당 메시지가 발견된 경우,

메시지에 대응하는 핸들러(CView 멤버 함수) 호출하도록 설계한다.

 

//Window procedure---------------------------------------------------

LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam)

{

        int i=0;

 

        while (CView::messageMap[i].iMsg!=0) {

               if (iMsg==CView::messageMap[i].iMsg) {

                       fpCViewGlobal=CView::messageMap[i].fp;

                       (app.*fpCViewGlobal)();

                       return 0;

               }//if

               ++i;

        }//while

        return DefWindowProc(hwnd,iMsg,wParam,lParam);

}//WndProc

 

 

==== 샘플 소스 ====

 

#include <windows.h>

 

//Forward declaration------------------------------------------------

LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,

                                              LPARAM lParam);

//class CObject;

//typedef void (CObject::*CObjectFunPointer)();

 

//static CObjectFunPointer fpCObjectGlobal;

//CObject* pCObject;

 

//Class CObject------------------------------------------------------

class CObject {

protected:

        static char szAppName[];

        HWND        hwnd;

        MSG         msg;

        WNDCLASSEX  wndclass;

public:

        void InitInstance(HINSTANCE hInstance,PSTR szCmdLine,

               int iCmdShow);

        void Run();

        WPARAM ExitInstance();

};//class CObject

 

void CObject::InitInstance(HINSTANCE hInstance,PSTR szCmdLine,int iCmdShow) {

        wndclass.cbSize         =sizeof(wndclass);

        wndclass.style          =CS_HREDRAW|CS_VREDRAW;

        wndclass.lpfnWndProc    =WndProc;

        wndclass.cbClsExtra     =0;

        wndclass.cbWndExtra     =0;

        wndclass.hInstance      =hInstance;

        wndclass.hIcon          =LoadIcon(NULL,IDI_APPLICATION);

        wndclass.hCursor        =LoadCursor(NULL,IDC_ARROW);

        wndclass.hbrBackground  =(HBRUSH)GetStockObject(WHITE_BRUSH);

        wndclass.lpszMenuName   =NULL;

        wndclass.lpszClassName  =szAppName;

        wndclass.hIconSm        =LoadIcon(NULL,IDI_APPLICATION);

 

        RegisterClassEx(&wndclass);

 

        hwnd=CreateWindow(szAppName,    //window class name

               "The Hello Program",        //window caption

               WS_OVERLAPPEDWINDOW,        //window style

               CW_USEDEFAULT,              //initial x position

               CW_USEDEFAULT,              //initial y position

               CW_USEDEFAULT,              //initial x size

               CW_USEDEFAULT,              //initial y size

               NULL,                       //parent window handle

               NULL,                       //window menu handle

               hInstance,                  //program instance handle

               NULL);                      //creation parameters

 

        ShowWindow(hwnd,iCmdShow);

        UpdateWindow(hwnd);

}//CObject::InitInstance

 

void CObject::Run() {

        while (GetMessage(&msg,NULL,0,0)) {

               TranslateMessage(&msg);

               DispatchMessage(&msg);

        }//while

}//CObject::Run

 

WPARAM CObject::ExitInstance() {

        return msg.wParam;

}//CObject::ExitInstance

 

char CObject::szAppName[]="HelloWin";

 

//class CView--------------------------------------------------------

class CView;

typedef void (CView::*CViewFunPointer)();

typedef struct tagMessageMap {

        UINT iMsg;

        CViewFunPointer fp;

} MessageMap;

static CViewFunPointer fpCViewGlobal;

//CView* pCView;

 

class CView : public CObject {

public:

        static MessageMap messageMap[];

public:

        void OnCreate();

        void OnDraw();

        void OnDestroy();

};//class CView

 

//{{BEGIN_MESSAGE_MAP

MessageMap CView::messageMap[]={

        {WM_CREATE,CView::OnCreate},

        {WM_PAINT,CView::OnDraw},

        {WM_DESTROY,CView::OnDestroy},

        {0,NULL}

};

//}}END_MESSAGE_MAP

 

//CView Event handler------------------------------------------------

void CView::OnCreate() {

}//CView::OnCreate

 

void CView::OnDraw() {

        HDC         hdc;

        PAINTSTRUCT ps;

        RECT        rect;

 

        hdc=BeginPaint(hwnd,&ps);

        GetClientRect(hwnd,&rect);

        DrawText(hdc,"Hello, Windows!",-1,&rect,

               DT_SINGLELINE|DT_CENTER|DT_VCENTER);

        EndPaint(hwnd,&ps);

}//CView::OnDraw

 

void CView::OnDestroy() {

        PostQuitMessage(0);

}//CView::OnDestroy

 

//Global object------------------------------------------------------

CView app;

 

//Window procedure---------------------------------------------------

LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam) {

        int i=0;

 

        while (CView::messageMap[i].iMsg!=0) {

               if (iMsg==CView::messageMap[i].iMsg) {

                       fpCViewGlobal=CView::messageMap[i].fp;

                       (app.*fpCViewGlobal)();

                       return 0;

               }//if

               ++i;

        }//while

        return DefWindowProc(hwnd,iMsg,wParam,lParam);

}//WndProc

 

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow) {

        app.InitInstance(hInstance,szCmdLine,iCmdShow);

        app.Run();

        return app.ExitInstance();

}//WinMain

 


==== 출처 : http://www.hanbitbook.co.kr/exam/1324 ====

'MFC' 카테고리의 다른 글

MFC 메시지 맵과 메시지 핸들링 원리  (0) 2008.08.30
CView클래스에 대해...Visual C++ 6 강좌(033)  (0) 2008.08.30
CView 클래스  (1) 2008.08.30
강력한 에디터 CRichEditView  (0) 2008.08.30
◎ MFC Class 레퍼런스(한글번역)  (0) 2008.08.30
지킴이 기초 강좌  (1) 2008.08.29
CCmdTarget Class MFC  (1) 2008.08.07