Win32 API
Sous-classement Windows
Recherche…
Introduction
Le sous-classement de fenêtres est un moyen de se connecter à une procédure de fenêtre standard et de modifier ou d'étendre son comportement par défaut. Une application sous-classe une fenêtre en remplaçant la procédure de fenêtre d'origine de la fenêtre par une nouvelle procédure de fenêtre. Cette nouvelle procédure de fenêtre reçoit tous les messages envoyés ou publiés dans la fenêtre.
Syntaxe
- 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, Msg UINT, WPARAM wParam, LPARAM lParam);
Paramètres
Paramètre | Détail |
---|---|
hwnd | Le handle de la fenêtre à la sous-classe. |
SubclassProc | La procédure de rappel de sous-classe. |
SubclassId | L'ID spécifié par l'utilisateur pour identifier la sous-classe, associé à la procédure de sous-classe, identifie de manière unique une sous-classe. Il peut simplement s'agir d'un nombre consécutif arbitraire. |
RefData | Données spécifiées par l'utilisateur. La signification est déterminée par l'application. Il est transmis au rappel de sous-classe de manière non modifiée. Cela pourrait être un pointeur d'objet sur une instance de classe par exemple. |
Remarques
Documentation MSDN
Sous-classement du bouton des fenêtres dans la classe C ++
Cet exemple montre comment manipuler la taille idéale du bouton en spécifiant une taille fixe.
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);
}
}
Installation et suppression de la procédure de sous-classe
Les méthodes suivantes permettent d'installer ou de supprimer le rappel de sous-classe. La combinaison de SubclassId
et SubclassProc
identifie de manière unique une sous-classe. Il n'y a pas de comptage de références, l'appel de SetWindowSubclass
plusieurs reprises avec différentes RefData
ne met à jour que cette valeur mais ne provoquera pas l'appel du rappel de sous-classes plusieurs fois.
BOOL SetWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DWORD_PTR RefData);
BOOL RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId);
Pour récupérer les données de référence transmises lors du dernier appel SetWindowSubclass
, vous pouvez utiliser la méthode GetWindowSubclass
.
BOOL GetWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DORD_PTR* RefData);
Paramètre | Détail |
---|---|
hwnd | Le handle de la fenêtre à la sous-classe. |
SubclassProc | La procédure de rappel de sous-classe. |
SubclassId | L'ID spécifié par l'utilisateur pour identifier la sous-classe, associé à la procédure de sous-classe, identifie de manière unique une sous-classe. Il peut simplement s'agir d'un nombre consécutif arbitraire. |
RefData | Données spécifiées par l'utilisateur. La signification est déterminée par l'application. Il est transmis au rappel de sous-classe de manière non modifiée. Cela pourrait être un pointeur d'objet sur une instance de classe par exemple. |
Le rappel de sous-classe est responsable d'appeler le gestionnaire suivant dans la chaîne de sous-classes de la fenêtre. DefSubclassProc
appelle le gestionnaire suivant dans la chaîne de sous-classe de la fenêtre. Le dernier gestionnaire appelle la procédure de fenêtre d'origine. Il doit être appelé dans toute procédure de rappel de sous-classement, à moins que le message ne soit complètement traité par l'application.
LRESULT DefSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
Paramètre | Détail |
---|---|
hwnd | Poignée de fenêtre d'où le message provient de |
Msg | Message de fenêtre |
wParam | Argument WPARAM, cette valeur dépend du message de fenêtre spécifique |
lParam | Argument LPARAM, cette valeur dépend du message de fenêtre spécifique |
SUBCLASSPROC
Il est similaire au rappel WINDOWPROC
mais contient un argument supplémentaire RefData
.
typedef LRESULT (CALLBACK *SUBCLASSPROC)(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
UINT_PTR SubclassId,
DWORD_PTR RefData
);
Gestion des messages de notification de contrôles communs dans la classe 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);
}
};