Win32 API
윈도우 서브 클래 싱
수색…
소개
윈도우 서브 클래 싱은 표준 윈도우 프로 시저에 연결하여 기본 동작을 수정하거나 확장하는 방법입니다. 응용 프로그램은 윈도우의 원래 윈도우 프로 시저를 새 윈도우 프로 시저로 바꿈으로써 윈도우를 서브 클래스합니다. 이 새 창 프로시 저는 창에 보내거나 게시 된 메시지를받습니다.
통사론
- BOOL SetWindowSubclass (HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DWORD_PTR RefData);
- BOOL RemoveWindowSubclass (HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId);
- BOOL GetWindowSubclass (HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DORD_PTR * RefData);
- LRESULT DefSubclassProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
매개 변수
매개 변수 | 세부 묘사 |
---|---|
hWnd | 서브 클래스하는 윈도우의 핸들. |
SubclassProc | 서브 클래스 콜백 프로 시저. |
SubclassId | 서브 클래스를 식별하기위한 사용자 지정 ID는 서브 클래스 프로시 듀어와 함게 서브 클래스를 고유하게 식별합니다. 단순히 임의의 연속 번호 일 수 있습니다. |
RefData | 사용자 지정 데이터. 의미는 응용 프로그램에 의해 결정됩니다. 변경되지 않은 방식으로 서브 클래스 콜백에 전달됩니다. 예를 들어 클래스 인스턴스에 대한 객체 포인터 일 수 있습니다. |
비고
MSDN 설명서
C ++ 클래스 내에서 윈도우 버튼 컨트롤 서브 클래 싱하기
이 예제는 고정 된 크기를 지정하여 버튼의 이상적인 크기를 조작하는 방법을 보여줍니다.
class ButtonSubclass {
public:
ButtonSubclass(HWND hWndButton) {
SetWindowSubclass(hWndButton, MyButtonSubclassProc, 1, (DWORD_PTR) this);
}
~ButtonSuclass() {
RemoveWindowSubclass(hWndButton, MyButtonSubclassProc, 1, (DWORD_PTR) this);
}
protected:
static LRESULT CALLBACK MyButtonSubclassProc(
HWND hWnd, UINT Msg, WPARAM w, LPARAM l, DWORD_PTR RefData) {
ButtonSubclass* o = reinterpret_cast<ButtonSubclass*>(RefData);
if (Msg == BCM_GETIDEALSIZE) {
reinterpret_cast<SIZE*>(lParam)->cx = 100;
reinterpret_cast<SIZE*>(lParam)->cy = 100;
return TRUE;
}
return DefSubclassProc(hWnd, Msg, w, l);
}
}
서브 클래스 프로 시저 설치 및 제거
다음 메소드는 서브 클래스 콜백을 설치하거나 제거합니다. SubclassId
와 SubclassProc
의 조합은 SubclassId
SubclassProc
고유하게 식별합니다. 참조 계산은 없으며 SetWindowSubclass
여러 번 호출하면 다른 RefData
만 해당 값을 업데이트하지만 하위 호출 콜백은 여러 번 호출되지 않습니다.
BOOL SetWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DWORD_PTR RefData);
BOOL RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId);
마지막 SetWindowSubclass
호출에서 전달 된 참조 데이터를 검색하려면 GetWindowSubclass
메서드를 사용할 수 있습니다.
BOOL GetWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DORD_PTR* RefData);
매개 변수 | 세부 묘사 |
---|---|
hWnd | 서브 클래스하는 윈도우의 핸들. |
SubclassProc | 서브 클래스 콜백 프로 시저. |
SubclassId | 서브 클래스를 식별하기위한 사용자 지정 ID는 서브 클래스 프로시 듀어와 함게 서브 클래스를 고유하게 식별합니다. 단순히 임의의 연속 번호 일 수 있습니다. |
RefData | 사용자 지정 데이터. 의미는 응용 프로그램에 의해 결정됩니다. 변경되지 않은 방식으로 서브 클래스 콜백에 전달됩니다. 예를 들어 클래스 인스턴스에 대한 객체 포인터 일 수 있습니다. |
서브 클래스 콜백은 윈도우의 서브 클래스 체인에서 다음 핸들러를 호출 할 책임이있다. DefSubclassProc
는 윈도우의 서브 클래스 체인에서 다음 핸들러를 호출합니다. 마지막 핸들러는 원래 윈도우 프로 시저를 호출합니다. 응용 프로그램이 메시지를 완전히 처리하지 않는 한 하위 클래 싱 콜백 프로 시저에서 호출해야합니다.
LRESULT DefSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
매개 변수 | 세부 묘사 |
---|---|
hWnd | 메시지가 발생한 창 핸들 |
메시지 | 창 메시지 |
wParam | WPARAM 인수.이 값은 특정 창 메시지에 따라 다릅니다. |
파라 패 | LPARAM 인수.이 값은 특정 창 메시지에 따라 다릅니다. |
SUBCLASSPROC
그것은 WINDOWPROC
콜백과 유사하지만 추가 인수 인 RefData
포함합니다.
typedef LRESULT (CALLBACK *SUBCLASSPROC)(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
UINT_PTR SubclassId,
DWORD_PTR RefData
);
C ++ 클래스 내의 공통 컨트롤 알림 메시지 처리
class MyToolbarControl {
public:
MyToolbarControl(HWND hWndToolbar, HWND hWndNotifyParent = nullptr) : _Handle(hWndToolbar) {
if (hWndNotifyParent == nullptr) {
hWndNotifyParent = GetAncestor(hWndToolbar, GA_ROOTOWNER);
}
SetWindowSubclass(
hWndNotifyParent , SubclassWindowProc, reinterpret_cast<UINT_PTR>(this), reinterpret_cast<DWORD_PTR>(this)
);
}
~MyToolbarControl() {
RemoveWindowSubclass(
hWndNotifyParent , SubclassWindowProc, reinterpret_cast<UINT_PTR>(this), reinterpret_cast<DWORD_PTR>(this)
);
}
protected:
HWND _Handle;
static LRESULT CALLBACK SubclassWindowProc(
HWND hWnd, UINT Msg, WPARAM w, LPARAM l, UINT_PTR SubclassId, DWORD_PTR RefData) {
MyToolbarControl * w = reinterpret_cast<MyToolbarControl *>(RefData);
if (Msg == WM_NOTIFY) {
NMHDR* h = reinterpret_cast<NMHDR*>(l);
if (h->hwndFrom == w->_Handle) {
// Handle notification message here...
}
}
return DefSubclassProc(hWnd, Msg, w, l);
}
};