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 |