Win32 API
Sottoclasse di Windows
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);
}
};