Win32 API
Windows-Unterklassifizierung
Suche…
Einführung
Die Fensterklassifizierung ist eine Möglichkeit, sich in die Standard-Fensterprozedur einzufügen und ihr Standardverhalten zu ändern oder zu erweitern. Eine Anwendung unterteilt ein Fenster, indem sie die ursprüngliche Fensterprozedur des Fensters durch eine neue Fensterprozedur ersetzt. Diese neue Fensterprozedur empfängt alle Nachrichten, die an das Fenster gesendet oder gesendet wurden.
Syntax
- 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);
Parameter
Parameter | Detail |
---|---|
hWnd | Der Griff des Fensters zur Unterklasse. |
SubclassProc | Die Callback-Prozedur der Unterklasse. |
SubclassId | Vom Benutzer angegebene ID zur Identifizierung der Unterklasse identifiziert zusammen mit der Unterklassenprozedur eindeutig eine Unterklasse Es kann sich einfach um eine beliebige fortlaufende Nummer handeln. |
RefData | Vom Benutzer angegebene Daten Die Bedeutung wird durch die Anwendung bestimmt. Sie wird unverändert an die Unterklasse Callback übergeben. Es könnte sich beispielsweise um einen Objektzeiger auf eine Klasseninstanz handeln. |
Bemerkungen
MSDN-Dokumentation
Windows-Schaltflächensteuerung innerhalb der C ++ - Klasse
In diesem Beispiel wird gezeigt, wie die ideale Größe der Schaltfläche durch Angabe einer festen Größe geändert wird.
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);
}
}
Verfahren zur Unterklasse installieren und entfernen
Die folgenden Methoden installieren oder entfernen den Rückruf der Unterklasse. Die Kombination von SubclassId
und SubclassProc
identifiziert eine SubclassProc
eindeutig. Es gibt keine Referenzzählung. SetWindowSubclass
mehrfache Aufruf von SetWindowSubclass
mit verschiedenen RefData
aktualisiert nur diesen Wert, bewirkt jedoch nicht, dass der Unterklassen-Callback mehrmals aufgerufen wird.
BOOL SetWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DWORD_PTR RefData);
BOOL RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId);
Um die Referenzdaten abzurufen, die im letzten SetWindowSubclass
Aufruf übergeben wurden, kann die GetWindowSubclass
Methode verwendet werden.
BOOL GetWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DORD_PTR* RefData);
Parameter | Detail |
---|---|
hWnd | Der Griff des Fensters zur Unterklasse. |
SubclassProc | Die Callback-Prozedur der Unterklasse. |
SubclassId | Vom Benutzer angegebene ID zur Identifizierung der Unterklasse identifiziert zusammen mit der Unterklassenprozedur eindeutig eine Unterklasse Es kann sich einfach um eine beliebige fortlaufende Nummer handeln. |
RefData | Vom Benutzer angegebene Daten Die Bedeutung wird durch die Anwendung bestimmt. Sie wird unverändert an die Unterklasse Callback übergeben. Es könnte sich beispielsweise um einen Objektzeiger auf eine Klasseninstanz handeln. |
Der Unterklassen-Callback ist dafür verantwortlich, den nächsten Handler in der Unterklassenkette von Window aufzurufen. DefSubclassProc
ruft den nächsten Handler in der Unterklassenkette des Fensters auf. Der letzte Handler ruft die ursprüngliche Fensterprozedur auf. Sie sollte in einer beliebigen Unterklassen-Rückrufprozedur aufgerufen werden, sofern die Nachricht nicht vollständig von der Anwendung verarbeitet wird.
LRESULT DefSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
Parameter | Detail |
---|---|
hWnd | Fensterhandle, von dem die Nachricht stammt |
Msg | Fenstermeldung |
wParam | WPARAM-Argument, dieser Wert hängt von einer bestimmten Fensternachricht ab |
lParam | LPARAM-Argument, dieser Wert hängt von bestimmten Fensternachrichten ab |
SUBCLASSPROC
Es ähnelt dem WINDOWPROC
Callback, enthält jedoch ein zusätzliches Argument RefData
.
typedef LRESULT (CALLBACK *SUBCLASSPROC)(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
UINT_PTR SubclassId,
DWORD_PTR RefData
);
Umgang mit Benachrichtigungsnachrichten für allgemeine Steuerungen innerhalb der C ++ - Klasse
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);
}
};