우선 클래스 멤버 함수를 윈도우 프로시져로 등록하는건 간단합니다.
아래처럼 클래스 선언에서 함수명 앞에 static를 붙여주기면 하면 됩니다.
class A
{
public:
HWND CreateEventWnd(HINSTANCE hInstance);
static LRESULT CALLBACK EventWndProc(HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam);
}
멤버 함수들은 보이지 않게 인자 하나를 추가로 더 전달받게 되는데요.
아시겠지만 this 포인터 입니다.
이 this 포인터가 인자로 하나 더 붙기 때문에 윈도우 프로시져가 될 수 없습니다.
그래서 this 포인터를 전달하기 않게 하기 위해 static 멤버로 만듭니다.
이렇게 하면 컴파일 에러 없이 잘 동작 합니다.
하지만 문제는 this 포인터를 전달받지 못하기 때문에
클래스의 다른 멤버들을 접근 할 수 없게 됩니다.
어떤 다른 방법을 통하여 this 포인터를 전해 줘야 합니다.
아래는 m_szMessage 멤버 변수에 들어있는 메시지를
윈도우 중앙에 뿌려주는 간단한 예제 입니다.
class A
{
public:
HWND CreateEventWnd(HINSTANCE hInstance);
static LRESULT CALLBACK EventWndProc(HWND hWnd, UINT nMsg, WPARAM wParam,
LPARAM lParam);
private:
char m_szMessage[256]; // 여기에 들어가는 메시지를 화면에 뿌려준다.
};
HWND A::CreateEventWnd(HINSTANCE hInstance)
{
// 메시지를 준비한다.
// 이 메시지가 윈도우 중앙에 뿌려진다.
strcpy(m_szMessage, "Hello, world!");
WNDCLASSEX wndclass;
wndclass.lpfnWndProc = EventWndProc;
......
// 윈도우를 생성할 때 this 포인터를 넘겨준다.
return CreateWindowEx(/*앞 부분 인자 생략*/, this);
}
LRESULT CALLBACK A::EventWndProc(HWND hWnd, UINT nMsg, WPARAM wParam,
LPARAM lParam)
{
A *pA; // this를 대신할 포인터 변수
switch(nMsg)
{
case WM_CREATE:
// 생성될 때 넘겨받은 this 포인터를 보관한다.
pA = *(A **) lParam;
SetWindowLong(hWnd, GWL_USERDATA, (LONG) pA);
return 0;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);
// this 포인터를 얻어온다.
pA = (A *) GetWindowLong(hWnd, GWL_USERDATA);
// 멤버에 접근 할 때는 pA-> 를 사용해서 접근한다.
// 그냥 m_szMessage만 달랑 쓰면 컴파일 에러가 날것이다.
DrawText(hDC, pA->m_szMessage, -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hWnd, &ps);
return 0;
}
return DefWindowProc(hWnd, nMsg, wParam, lParam);
}
위에것은 구식의 방법이다..
요즘의 밑에 방법으로 -0-/
------------------------------------------------------------------------------
class A
{
public:
HWND CreateEventWnd(HINSTANCE hInstance);
static LRESULT CALLBACK EventWndProc(HWND hWnd, UINT nMsg, WPARAM wParam,
LPARAM lParam);
private:
char m_szMessage[256]; // 여기에 들어가는 메시지를 화면에 뿌려준다.
};
HWND A::CreateEventWnd(HINSTANCE hInstance)
{
// 메시지를 준비한다.
// 이 메시지가 윈도우 중앙에 뿌려진다.
strcpy(m_szMessage, "Hello, world!");
WNDCLASSEX wndclass;
wndclass.lpfnWndProc = EventWndProc;
......
// 윈도우를 생성할 때 this 포인터를 넘겨준다.
return CreateWindowEx(/*앞 부분 인자 생략*/, this);
}
LRESULT CALLBACK A::EventWndProc(HWND hWnd, UINT nMsg, WPARAM wParam,
LPARAM lParam)
{
static A *pA; // this를 대신할 포인터 변수
switch(nMsg)
{
case WM_CREATE:
// 생성될 때 넘겨받은 this 포인터를 보관한다.
pA = (A *)(((LPCREATESTRUCT)lParam)->lpCreateParams);
return 0;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);
// 멤버에 접근 할 때는 pA-> 를 사용해서 접근한다.
// 그냥 m_szMessage만 달랑 쓰면 컴파일 에러가 날것이다.
DrawText(hDC, pA->m_szMessage, -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hWnd, &ps);
return 0;
}
return DefWindowProc(hWnd, nMsg, wParam, lParam);
}
'MFC' 카테고리의 다른 글
RTTI의 이해 (0) | 2008.09.02 |
---|---|
MFC 프로그램의 흐름 살펴보기 - 인터널 (1) | 2008.09.01 |
AfxEndDeferRegisterClass, AfxWndProc - MFC 살펴보기 (0) | 2008.09.01 |
클래스 맴버함수를 콜백함수로 사용하기 [2/3] (1) | 2008.09.01 |
클래스 멤버함수를 윈도우 프로시저로 사용하기 [1/3] (1) | 2008.09.01 |
MFC 메인 윈도우의 생성 흐름 (1) | 2008.09.01 |
MFC 팁들 (0) | 2008.09.01 |