Win32 API
Windows-subklasse
Zoeken…
Invoering
Venstersubklasse is een manier om aan te sluiten op de standaard vensterprocedure en het standaardgedrag te wijzigen of uit te breiden. Een toepassing subklasseert een venster door de oorspronkelijke vensterprocedure van het venster te vervangen door een nieuwe vensterprocedure. Deze nieuwe vensterprocedure ontvangt alle berichten die naar het venster zijn verzonden of gepost.
Syntaxis
- 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);
parameters
Parameter | Detail |
---|---|
hWnd | De greep van het venster naar subklasse. |
SubclassProc | De terugroepprocedure van de subklasse. |
SubclassId | Door de gebruiker opgegeven ID om de subklasse te identificeren, identificeert samen met de subklasse-procedure een unieke subklasse. Het kan eenvoudig een willekeurig opeenvolgend nummer zijn. |
rEFDATA | Door de gebruiker opgegeven gegevens. De betekenis wordt bepaald door de toepassing. Het wordt op ongewijzigde wijze doorgegeven aan de subklasse callback. Het kan bijvoorbeeld een objectpointer zijn naar een klasse-instantie. |
Opmerkingen
MSDN-documentatie
Subklasse Windows-knopbediening binnen C ++ klasse
Dit voorbeeld laat zien hoe u de ideale knopgrootte kunt manipuleren door een vaste grootte op te geven.
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);
}
}
Procedure voor subklasse installeren en verwijderen
Met de volgende methoden wordt de callback van de subklasse geïnstalleerd of verwijderd. De combinatie van SubclassId
en SubclassProc
identificeert op unieke wijze een subklasse. Er is geen referentietelling, het aanroepen van SetWindowSubclass
meerdere keren met verschillende RefData
alleen die waarde bij, maar zorgt er niet voor dat de callback van de subklasse meerdere keren wordt aangeroepen.
BOOL SetWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DWORD_PTR RefData);
BOOL RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId);
Om de referentiegegevens op te halen die zijn doorgegeven tijdens de laatste SetWindowSubclass
aanroep, kan men de methode GetWindowSubclass
gebruiken.
BOOL GetWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DORD_PTR* RefData);
Parameter | Detail |
---|---|
hWnd | De greep van het venster naar subklasse. |
SubclassProc | De terugroepprocedure van de subklasse. |
SubclassId | Door de gebruiker opgegeven ID om de subklasse te identificeren, identificeert samen met de subklasse-procedure een unieke subklasse. Het kan eenvoudig een willekeurig opeenvolgend nummer zijn. |
rEFDATA | Door de gebruiker opgegeven gegevens. De betekenis wordt bepaald door de toepassing. Het wordt op ongewijzigde wijze doorgegeven aan de subklasse callback. Het kan bijvoorbeeld een objectpointer zijn naar een klasse-instantie. |
De callback van de subklasse is verantwoordelijk voor het aanroepen van de volgende handler in de subklasse chain van het venster. DefSubclassProc
roept de volgende handler in de subklasse keten van het venster aan. De laatste handler roept de oorspronkelijke vensterprocedure op. Het moet worden aangeroepen in elke subklasse callback-procedure, tenzij het bericht volledig wordt afgehandeld door de toepassing.
LRESULT DefSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
Parameter | Detail |
---|---|
hWnd | Venstergreep waar het bericht vandaan komt |
Msg | Venster bericht |
wParam | WPARAM-argument, deze waarde is afhankelijk van een specifiek vensterbericht |
lParam | LPARAM-argument, deze waarde is afhankelijk van een specifiek vensterbericht |
SUBCLASSPROC
Het is vergelijkbaar met WINDOWPROC
callback maar bevat een extra argument RefData
.
typedef LRESULT (CALLBACK *SUBCLASSPROC)(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
UINT_PTR SubclassId,
DWORD_PTR RefData
);
Omgaan met algemene besturingsmeldingen binnen de klasse 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);
}
};