Win32 API
Subclase de Windows
Buscar..
Introducción
La subclasificación de ventanas es una forma de conectarse al procedimiento de ventana estándar y modificar o ampliar su comportamiento predeterminado. Una aplicación asigna subclases a una ventana reemplazando el procedimiento de ventana original de la ventana con un nuevo procedimiento de ventana. Este nuevo procedimiento de ventana recibe cualquier mensaje enviado o publicado en la ventana.
Sintaxis
- 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);
Parámetros
Parámetro | Detalle |
---|---|
hWnd | El manejador de la ventana a subclase. |
SubclaseProc | El procedimiento de devolución de llamada de subclase. |
Subclase | El ID especificado por el usuario para identificar la subclase, junto con el procedimiento de la subclase identifica de forma única una subclase. Simplemente puede ser un número consecutivo arbitrario. |
Datos de referencia | Datos especificados por el usuario. El significado está determinado por la aplicación. Se pasa a la devolución de llamada de la subclase en forma no modificada. Podría ser un puntero de objeto a una instancia de clase, por ejemplo. |
Observaciones
Documentación MSDN
Subclasificar el control de botones de ventanas dentro de la clase C ++
Este ejemplo muestra cómo manipular el tamaño ideal del botón especificando un tamaño fijo.
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);
}
}
Procedimiento de instalación y eliminación de subclases.
Los siguientes métodos instalan o eliminan la devolución de llamada de la subclase. La combinación de SubclassId
y SubclassProc
identifica de forma única una subclase. No hay un recuento de referencias, llamar a SetWindowSubclass
varias veces con diferentes RefData
solo actualiza ese valor, pero no hace que la devolución de llamada de la subclase se llame varias veces.
BOOL SetWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DWORD_PTR RefData);
BOOL RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId);
Para recuperar los datos de referencia que se pasaron en la última llamada a SetWindowSubclass
, se puede usar el método GetWindowSubclass
.
BOOL GetWindowSubclass(HWND hWnd, SUBCLASSPROC SubclassProc, UINT_PTR SubclassId, DORD_PTR* RefData);
Parámetro | Detalle |
---|---|
hWnd | El manejador de la ventana a subclase. |
SubclaseProc | El procedimiento de devolución de llamada de subclase. |
Subclase | El ID especificado por el usuario para identificar la subclase, junto con el procedimiento de la subclase identifica de forma única una subclase. Simplemente puede ser un número consecutivo arbitrario. |
Datos de referencia | Datos especificados por el usuario. El significado está determinado por la aplicación. Se pasa a la devolución de llamada de la subclase en forma no modificada. Podría ser un puntero de objeto a una instancia de clase, por ejemplo. |
La devolución de llamada de la subclase es responsable de llamar al siguiente controlador en la cadena de subclases de la ventana. DefSubclassProc
llama al siguiente controlador en la cadena de subclases de la ventana. El último controlador llama al procedimiento de ventana original. Debe llamarse en cualquier procedimiento de devolución de llamada de subclases, a menos que la aplicación maneje completamente el mensaje.
LRESULT DefSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
Parámetro | Detalle |
---|---|
hWnd | Manejador de ventana desde donde se origina el mensaje |
Msg | Mensaje de ventana |
wParam | Argumento WPARAM, este valor depende del mensaje de ventana específico |
Param | Argumento LPARAM, este valor depende del mensaje de ventana específico |
SUBCLASSPROC
Es similar a la WINDOWPROC
llamada de WINDOWPROC
pero contiene un argumento adicional RefData
.
typedef LRESULT (CALLBACK *SUBCLASSPROC)(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
UINT_PTR SubclassId,
DWORD_PTR RefData
);
Manejo de mensajes de notificación de controles comunes dentro de la clase 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);
}
};