처음 subclassing을 시도하는 사람들이 흔히 실수하는 부분이라 정리하려고 한다.
* Subclassing은 무엇인가?
Subclassing은 기존에 존재하는 컨트롤(예: button)을 자신의 입맛에 맞게 바꾸기 위한 기법이다.
Superclassing이란 개념도 있지만, Subclassing은 좀 다르다. 우선은 Subclassing을 설명해야 하니 패스.
보통 Windows에서 Subclassing은 해당 control의 wndproc()을 바꾸어서 내가 원하는 message loop를 수행하도록 하는데, 메시지 후킹과 비슷하다고 생각하면 된다. (그것도 합법적으로)
메시지 후킹만 되냐? 아니다. 새로운 메시지를 직접 처리할 수 있으며, 처리 후 old_wndproc()로 메시지를 넘겨주면 기존에 수행하던 동작을 그대로 지니며 새로운 행동을 정의 할 수 있다.
이렇게 말하면 어려우니 간단하게 생각하자.
우리가 흔히 사용하는 CDialog가 있는데, Dialog-based로 프로젝트를 생성하면 CMyDlg 와 같은 CDialog를 상속받은 Dialog 클래스가 생성된다.
이 클래스는 CDialog를 Subclassing 했다고 생각하면 된다.
다른 예를 들면 CStatic이 있다고 할 때, CStatic에 그림을 그려주고 싶다면 CStatic을 상속받은 뒤 WM_PAINT에서 그림을 그려주면 된다.
지금 예로 들은것들은 모두 MFC 기준이지만, API 차원에서도 GetWindowLong()을 이용하여 함수의 wndproc을 얻어와서 내가 원하는 wndproc를 실행하게 할 수 있다.
그렇다면 무엇이 문제일까?
Subclassing 된 컨트롤은 WM_CREATE 메시지를 받지 못한다. 정확히는 Dialog에 그려넣은 Control에서 이런 문제가 발생한다.
이는 resource에 포함된 dialog가 생성될 때 초기화 되는 관계로 발생되는 문제이며, OnCreate, PreCreateWindow() 모두 동작하지 않는다.
해결책은 PreSubclassWindow에서 처리하는 방법이다.
(너무 간단한가;;)
Posted by 장현준


