2009. 6. 29. 20:43

MDI에서 Subclassing 활용

MDI에서 Child Frame 을  생성하는 등의 일을 하는 CMDIFrameWnd의 멤버 m_hWndMDIClient 의 Window Procedure 를 재정의하면 WM_MIDCREATE 메시지를 재정의할 수도 있다.

CMDIFrameWnd 의 OnCreate 에서
 LRESULT FAR PASCAL SubClassFunc2(HWND hWnd,UINT Message,WPARAM wParam,
                                 LPARAM lParam);
FARPROC lpfnOldWndProc2 = NULL;

....

CMainFrame::OnCreate()
{
if(lpfnOldWndProc2 == NULL && m_hWndMDIClient != NULL)
        lpfnOldWndProc2 = (FARPROC)SetWindowLong(m_hWndMDIClient,    GWL_WNDPROC, (DWORD) SubClassFunc2);
}


그리고 핸들러는 다음과 같다.

 LRESULT FAR PASCAL SubClassFunc2(   HWND hWnd,
                                UINT Message,
                                WPARAM wParam,
                                LPARAM lParam)
{
    if( Message == WM_MDICREATE)
        ASSERT(FALSE);

    return CallWindowProc((WNDPROC)lpfnOldWndProc2, hWnd, Message, wParam,
        lParam);
}

OnDestroy 에서 다시 원본 프로시저를 반환하는 것은 좋은 습관일 것이다.

 void CMainFrame::OnDestroy()
{
SetWindowLong(GetSafeHwnd(), GWL_WNDPROC, (DWORD) lpfnOldWndProc);
...
}



이런 식으로 SubClassing 을 활용하면 여러 메시지를 재정의할 수 있을 것이다. 후킹도 이와 비슷하지만 조금 사용하기가 까칠하잖아...

근데 의아해 할지도... 굳이 WM_MDICREATE 를 재정의할 필요가라고? .. ㅎㅎ 그러게...

그치만, CMainFrame 의 멤버로 있는 m_hWndMDIClient 관련 메시지는 재정의할 수 없을거라 생각했다. 주로 MFC를 다루다 보니, 서브클래싱보다는 메시지 핸들러를 이용하고 HWND 보다는 CWnd 를 주로 사용하기 때문이 아닐까. 이런식으로 하나를 오랫동안 다루다 보면 가끔씩 사고가 갑갑하고 막힐때가 있다.