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);
    }
};


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow