Win32 API
Podklasowanie systemu Windows
Szukaj…
Wprowadzenie
Podklasowanie okien jest sposobem na przyłączenie się do standardowej procedury okna i zmodyfikowanie lub rozszerzenie jej domyślnego zachowania. Aplikacja podklasuje okno, zastępując oryginalną procedurę okna nową procedurą okna. Ta nowa procedura okna odbiera wszelkie wiadomości wysłane lub wysłane do okna.
Składnia
- 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);
Parametry
Parametr | Szczegół |
---|---|
hWnd | Uchwyt okna do podklasy. |
SubclassProc | Procedura wywołania zwrotnego podklasy. |
SubclassId | Podany przez użytkownika identyfikator identyfikujący podklasę, wraz z procedurą podklasy jednoznacznie identyfikuje podklasę. Może to być po prostu dowolny kolejny numer. |
RefData | Dane określone przez użytkownika. Znaczenie jest określone przez aplikację. Jest przekazywany do wywołania zwrotnego podklasy w niezmodyfikowany sposób. Może to być na przykład wskaźnik obiektu do instancji klasy. |
Uwagi
Dokumentacja MSDN
Kontrola przycisków Windows w podklasach w klasie C ++
Ten przykład pokazuje, jak manipulować idealnym rozmiarem przycisku, określając stały rozmiar.
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);
}
}
Instalowanie i usuwanie procedury podklasy
Poniższe metody instalują lub usuwają wywołanie zwrotne podklasy. Połączenie SubclassId
i SubclassProc
jednoznacznie identyfikuje podklasę. Nie ma liczenia referencji, wywoływanie SetWindowSubclass
wiele razy z różnymi RefData
tylko aktualizuje tę wartość, ale nie powoduje wielokrotnego wywoływania wywołania podklasy.
BOOL SetWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DWORD_PTR RefData);
BOOL RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId);
Aby pobrać dane referencyjne przekazane w ostatnim wywołaniu SetWindowSubclass
, można użyć metody GetWindowSubclass
.
BOOL GetWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DORD_PTR* RefData);
Parametr | Szczegół |
---|---|
hWnd | Uchwyt okna do podklasy. |
SubclassProc | Procedura wywołania zwrotnego podklasy. |
SubclassId | Podany przez użytkownika identyfikator identyfikujący podklasę, wraz z procedurą podklasy jednoznacznie identyfikuje podklasę. Może to być po prostu dowolny kolejny numer. |
RefData | Dane określone przez użytkownika. Znaczenie jest określone przez aplikację. Jest przekazywany do wywołania zwrotnego podklasy w niezmodyfikowany sposób. Może to być na przykład wskaźnik obiektu do instancji klasy. |
Wywołanie zwrotne podklasy jest odpowiedzialne za wywołanie następnego modułu obsługi w łańcuchu podklasy okna. DefSubclassProc
wywołuje następną procedurę obsługi w łańcuchu podklas okna. Ostatni moduł obsługi wywołuje oryginalną procedurę okna. Powinien być wywoływany w dowolnej procedurze wywołania zwrotnego podklasy, chyba że aplikacja jest całkowicie obsługiwana.
LRESULT DefSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
Parametr | Szczegół |
---|---|
hWnd | Uchwyt okna, z którego pochodzi wiadomość |
Msg | Komunikat w oknie |
wParam | Argument WPARAM, ta wartość zależy od konkretnego komunikatu okna |
Param | Argument LPARAM, ta wartość zależy od konkretnego komunikatu okna |
SUBCLASSPROC
Jest podobny do wywołania zwrotnego WINDOWPROC
ale zawiera dodatkowy argument RefData
.
typedef LRESULT (CALLBACK *SUBCLASSPROC)(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
UINT_PTR SubclassId,
DWORD_PTR RefData
);
Obsługa powiadomień o typowych kontrolach w klasie 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);
}
};