음... 일단은 윈도우 관련해서 따로 클래스로 관리할 필요가 있었는데, 다들 알겠지만 this 포인터 때문에 그렇게 간단하게 넣을 수 없다.
나는 윈도우 만들때 여분 메모리를 할당받아서 거기에 주소값을 넣어두고 static 프로시저에서 그 주소값을 꺼내와서 그 오브젝트의 프로시저를 호출하는 방식으로 해결하였다.
일단 Game 클래스 내부에 static 프로시저인 HandleWndProc과 내부에서 사용할 WndProc이 있다.
1) WNDCLASSEX cbWndExtra에 포인터 사이즈를 대입하였다. 프로시저는 하던대로 static 프로시저를 대입하여주었다.
WNDCLASSEX wndClass; ZeroMemory(&wndClass, sizeof(WNDCLASSEX));
wndClass.lpfnWndProc = Game::HandleWndProc;
... wndClass.cbWndExtra = sizeof(Game*);
...
RegisterClassEx(&wndClass);
2) 윈도우를 만들고 0인덱스에 주소값을 저장한다.
SetWindowLongPtr(m_hWnd, 0, reinterpret_cast<LONG_PTR>(this));
3)static 프로시저를 다음과 같이 작성한다.
LRESULT CALLBACK Game::HandleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { Game * localFrame = reinterpret_cast<Game *>(GetWindowLongPtr(hWnd, 0)); if (localFrame) { return localFrame->WndProc(hWnd, msg, wParam, lParam); } else { return DefWindowProc(hWnd, msg, wParam, lParam); } }
cpp 파일이기 때문에 static 키워드가 없지만 위에서 서술한 것과 같이 HandleWndProc은 static 함수이다. 메시지루프에서 DisptchMessage에 의해 해당 함수가 호출되게 되면 해당 주소를 가져와서 형변환을 한 다음, 해당 오브젝트의 프로시저를 호출하는 식이다.
다른 방식도 한번 시간날때 생각해보고 올리도록 하겠다
댓글