|
MFC의 경우, 가상함수(virtual function)를 이용해서 이 Subclassing을 자동으로 처리해 주고 있다. 즉, 사용자가 어떤 객체 클래스에서 파생하여 다른 클래스를 만들어 내었다면 이것이 바로 Subclassing이 되고 있는 것이다.
그런데, 이 클래스를 이용해서 객체를 생성하는 것이 아니고, 이미 존재하고 있는 다른 클래스의 객체를 이 클래스로 바꾸어 줄려면, 메시지 처리함수를 교체 해주는 과정을 거쳐야 한다. 이러한 기능을 해주는 함수가 CWnd::SubclassWindow()함수이고, 이 함수를 사용해서 구현된 편리한 함수로 CWnd::SubclassDlgItem()이 있다. 그러나, 이 함수들을 사용하는 방법은 MFC 2.x와 MFC 4.x에서 각각 다르다. 또한, 서브클래스된 상태를 해제하기 위한 함수가 필요한데, MFC 4.x에서는 CWnd::UnsubclassWindow()라는 함수가 존재한다. 그러면, 각각의 사용법에 대해서 보기로 하자. [MFC 4.x] 새로운 클래스의 객체를 아래와 같이 선언하고, 바꾸고자 하는, 이미 존재하는 창의 핸들이나 ID를 가지고 서브클래싱을 해주면 된다. CNewClassWnd m_wndNewWnd; m_wndNewWnd.SubclassWindow(m_pOriginalWnd); 또는 m_wndNewWnd.SubclassDlgItem(ID_ORIGINAL_WND); 그리고, 서브클래싱을 해제할 때는, m_wndNewWnd.UnsubclassWindow()와 같이 불러 주면 된다. [MFC 2.x] MFC 4.x의 경우, MFC 2.x의 복잡함을 줄이기 위해서 단순하게 고쳤다고 볼 수가 있다. 원래, MFC 2.x에서는CWnd::GetSuperWndProcAddr()함수를 구현해 주어야 하고, CWnd::UnsubclassWindow()함수가 존재하지 않는다. 여기에서, CWnd::GetSuperWndProcAddr()란 Subclassing을 할 때, 원래 메시지처리함수의 포인터를 저장하기 위한 장소를 알아내기 위해서 MFC가 부르는 함수이다. 그래서, 우리는 이 함수를 이용해서 그 포인터를 저장할 변수의 주소를 알려 주면 된다. 이 함수를 구현하는 것은 아래와 같다. ① 우선, 헤더파일에서 함수와 메시지처리함수의 포인터를 저장할 장소를 선언을 한다. static WNDPROC m_lpSuperWndProc; virtual WNDPROC* GetSuperWndProcAddr(); ② 정적변수로 선언을 했으므로, 프로그램파일에서 다시 선언해주고, 함수를 아래와 같이 선언해 준다. WNDPROC CNewWnd::m_lpSuperWndProc; WNDPROC* CNewWnd::GetSuperWndProcAddr() { return &m_lpSuperWndProc; } 위와 같이, 이 함수는 단순히 포인터를 저장할 변수의 포인터를 넘겨주는 역할만을 한다. 그러므로, 이러한 함수가 MFC 4.x에서는 사라지는 것이 당연하게 보인다.그리고, 생성자에서 이 변수를 NULL로 초기화 시켜 주어도 좋다. 그러면, 이제 UnsubclassWindow()함수를 구현해 보자. 이 함수는 컨트롤을 고치기 위한 목적으로는 별로 쓸 일이 없지만, 일반적인 창을 고치거나 할 때는 사용자의 요구에 따라서 창을 원래의 클래스로 바꾸어 줄 경우도 있기 때문에 꼭 필요하게 된다. 이 함수는 Subclassing과정을 거꾸로 구현해 주면 된다. void CNewWnd::UnsubclassWindow() { WNDPROC* lpfnCurrentFn; lpfnCurrentFn = GetSuperWndProcAddr(); ::SetWindowLong(m_hWnd, GWL_WNDPROC, (DWORD)(* lpfnCurrentFn)); return; } 이 글과 관련있는 글을 자동검색한 결과입니다 [?]
|
카테고리
이전블로그
이글루링크
최근 등록된 덧글
| ||||||