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


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow