TN001: Registro de clases de ventana

En esta nota se describen las rutinas MFC que registran las clases WNDCLASS que necesita Microsoft Windows. Se describen los atributos WNDCLASS específicos que usan MFC y Windows.

El problema

Los atributos de un objeto CWnd, como un identificador HWND en Windows, se almacenan en dos lugares: el objeto de ventana y WNDCLASS. El nombre de WNDCLASS se pasa a funciones generales de creación de ventanas como CWnd::Create y CFrameWnd::Create en el parámetro lpszClassName.

WNDCLASS debe registrarse mediante uno de los cuatro medios:

  • Implícitamente, mediante una MFC WNDCLASS proporcionada.

  • Implícitamente, mediante la creación de subclases de un control de Windows (u otro control).

  • Explícitamente, llamando a AfxRegisterWndClass o AfxRegisterClass de MFC.

  • Explícitamente, llamando a la rutina de WindowsRegisterClass de.

Campos WNDCLASS

La estructura WNDCLASS consta de varios campos que describen una clase de ventana. En la tabla siguiente se muestran los campos y se especifica cómo se usan en una aplicación MFC:

Campo Descripción
lpfnWndProc Proc. de ventana, debe ser un AfxWndProc
cbClsExtra No se usa (debe ser cero)
cbWndExtra No se usa (debe ser cero)
hInstance Se rellena automáticamente con AfxGetInstanceHandle
hIcon Icono de ventanas de marco, véase a continuación
hCursor Cursor para cuando el mouse está encima de la ventana, véase a continuación
hbrBackground Color de fondo, véase a continuación
lpszMenuName No se usa (debe ser NULL)
lpszClassName Nombre de clase, véase a continuación

Clases WNDCLASS proporcionadas

Las versiones anteriores de MFC (anteriores a MFC 4.0), proporcionaban varias clases de ventanas predefinidas, pero ya no se proporcionan de forma predeterminada. Las aplicaciones deben usar AfxRegisterWndClass con los parámetros adecuados.

Si la aplicación proporciona un recurso con el identificador de recurso especificado (por ejemplo, AFX_IDI_STD_FRAME), MFC lo usará; de lo contrario, usará el recurso predeterminado. Para el icono, se usa el icono de aplicación estándar y, para el cursor, se usa el cursor de flecha estándar.

Dos iconos admiten aplicaciones MDI con tipos de documento únicos: un icono para la aplicación principal, el otro para las ventanas MDIChild y documentos emblemáticos. Para varios tipos de documentos con diferentes iconos, debe registrar elementos WNDCLASS adicionales o usar la función CFrameWnd::LoadFrame.

CFrameWnd::LoadFrame registrará una clase WNDCLASS mediante el identificador de icono que especifique como primer parámetro y los siguientes atributos estándar:

  • estilo de clase : CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;

  • icono AFX_IDI_STD_FRAME

  • cursor de flecha

  • color de fondo COLOR_WINDOW

Los valores de color de fondo y cursor para CMDIFrameWnd no se usan, ya que el área cliente de CMDIFrameWnd está completamente cubierta por la ventana MDICLIENT. Microsoft no recomienda la subclase de la ventana MDICLIENT, por lo que use los colores y tipos de cursor estándar siempre que sea posible.

Controles de subclases y superclases

Si crea subclases o superclases de un control de Windows (por ejemplo, CButton), la clase obtiene automáticamente los atributos WNDCLASS proporcionados en la implementación de Windows de ese control.

Función AfxRegisterWndClass

MFC proporciona una función auxiliar para registrar una clase de ventana. Dado un conjunto de atributos (estilo de clase de ventana, cursor, pincel de fondo e icono), se genera un nombre sintético y se registra la clase de ventana resultante. Por ejemplo,

const char* AfxRegisterWndClass(UINT nClassStyle,
    HCURSOR hCursor,
    HBRUSH hbrBackground,
    HICON hIcon);

Esta función devuelve una cadena temporal del nombre de clase de ventana registrado generado. Para obtener más información sobre esta función, vea AfxRegisterWndClass.

La cadena devuelta es un puntero temporal a un búfer de cadena estático. Es válido hasta la siguiente llamada a AfxRegisterWndClass. Si quiere seguir manteniendo esta cadena, almacénela en una variable CString, como en este ejemplo:

CString strWndClass = AfxRegisterWndClass(CS_DBLCLK, ...);

...
CWnd* pWnd = new CWnd;
pWnd->Create(strWndClass, ...);

...

AfxRegisterWndClass producirá una excepción CResourceException si la clase de ventana no se pudo registrar (ya sea debido a parámetros incorrectos o a memoria insuficiente de Windows).

Funciones RegisterClass y AfxRegisterClass

Si quiere algo más sofisticado que lo que proporciona AfxRegisterWndClass, puede llamar a la API de Windows RegisterClass o a la función MFC AfxRegisterClass. Las funciones CWnd, CFrameWnd y CMDIChildWndCreate toman un nombre de cadena lpszClassName para la clase de ventana como primer parámetro. Puede usar cualquier nombre de clase de ventana registrado, independientemente del método que usó para registrarlo.

Es importante usar AfxRegisterClass (o AfxRegisterWndClass) en un archivo DLL en Win32. Win32 no anula automáticamente el registro de clases registradas por un archivo DLL, por lo que debe anular explícitamente el registro de las clases cuando finalice el archivo DLL. Esto se controla automáticamente al usar AfxRegisterClass en lugar de RegisterClass. AfxRegisterClass mantiene una lista de clases únicas registradas por el archivo DLL y las anulará automáticamente cuando finalice el archivo DLL. Cuando usa RegisterClass en un archivo DLL, debe asegurarse de que todas las clases no se registran cuando finaliza el archivo DLL (en la función DllMain). Si no lo hace, es posible que RegisterClass produzca un error inesperado cuando otra aplicación cliente intente usar el archivo DLL.

Consulte también

Notas técnicas por número
Notas técnicas por categoría