Ricerca…


introduzione

La sottoclasse della finestra è un modo per collegarsi alla procedura della finestra standard e per modificare o estendere il suo comportamento predefinito. Un'applicazione sottoclasse una finestra sostituendo la procedura della finestra originale della finestra con una nuova finestra. Questa nuova finestra riceve tutti i messaggi inviati o inviati alla finestra.

Sintassi

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

Parametri

Parametro Dettaglio
hWnd La maniglia della finestra per sottoclasse.
SubclassProc La procedura di callback sottoclasse.
SubclassId L'ID specificato dall'utente per identificare la sottoclasse, unitamente alla procedura sottoclasse, identifica in modo univoco una sottoclasse. Può semplicemente essere un numero consecutivo arbitrario.
rEFDATA Dati specificati dall'utente. Il significato è determinato dall'applicazione. Viene passato alla callback della sottoclasse in modo non modificato. Ad esempio, potrebbe essere un puntatore a un oggetto di classe.

Osservazioni

Documentazione MSDN

Controllo del sottoclasse di pulsanti di Windows all'interno della classe C ++

Questo esempio mostra come manipolare la dimensione ideale del pulsante specificando una dimensione fissa.

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

Installazione e rimozione della procedura di sottoclasse

I seguenti metodi installano o rimuovono il callback della sottoclasse. La combinazione di SubclassId e SubclassProc identifica in modo univoco una sottoclasse. Non esiste un conteggio dei riferimenti, chiamando SetWindowSubclass più volte con RefData diversi aggiorna solo quel valore ma non causa il richiamo della callback della sottoclasse più volte.

BOOL SetWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DWORD_PTR RefData);
BOOL RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId);

Per recuperare i dati di riferimento passati nell'ultima chiamata SetWindowSubclass , è possibile utilizzare il metodo GetWindowSubclass .

BOOL GetWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DORD_PTR* RefData);
Parametro Dettaglio
hWnd La maniglia della finestra per sottoclasse.
SubclassProc La procedura di callback sottoclasse.
SubclassId L'ID specificato dall'utente per identificare la sottoclasse, unitamente alla procedura sottoclasse, identifica in modo univoco una sottoclasse. Può semplicemente essere un numero consecutivo arbitrario.
rEFDATA Dati specificati dall'utente. Il significato è determinato dall'applicazione. Viene passato alla callback della sottoclasse in modo non modificato. Ad esempio, potrebbe essere un puntatore a un oggetto di classe.

Il callback della sottoclasse è responsabile di chiamare il prossimo handler nella catena della sottoclasse della finestra. DefSubclassProc chiama il gestore successivo nella catena della sottoclasse della finestra. L'ultimo gestore chiama la procedura della finestra originale. Dovrebbe essere chiamato in qualsiasi procedura di callback di sottoclassi a meno che il messaggio non sia completamente gestito dall'applicazione.

LRESULT DefSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
Parametro Dettaglio
hWnd Maniglia della finestra da cui proviene il messaggio
Msg Messaggio finestra
wParam Argomento WPARAM, questo valore dipende dal messaggio specifico della finestra
lParam Argomento LPARAM, questo valore dipende dal messaggio specifico della finestra

SUBCLASSPROC

È simile al callback WINDOWPROC ma contiene un argomento aggiuntivo RefData .

typedef LRESULT (CALLBACK *SUBCLASSPROC)(
    HWND hWnd,
    UINT Msg,
    WPARAM wParam,
    LPARAM lParam,
    UINT_PTR SubclassId,
    DWORD_PTR RefData
);

Gestione dei messaggi di notifica dei controlli comuni all'interno della 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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow