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.