Esta nota técnica describe la reflexión de mensajes, una característica nueva de MFC 4.0. También contiene instrucciones para crear un control reutilizable simple que utiliza la reflexión de mensaje.
Esta nota técnica no discutir reflexión mensaje tal como se aplica a los controles ActiveX (anteriormente denominados controles OLE). Consulte el artículo controles ActiveX: crear subclases de un Control de Windows en la Guía del programador de Visual C++.
¿Cuál es el reflexión de mensaje?
Controles de formularios Windows envían mensajes de notificación con frecuencia a sus ventanas de padre. Por ejemplo, muchos controles de envían un mensaje de notificación de color control (WM_CTLCOLOR o una de sus variantes) a sus padres para permitir que el padre suministrar un pincel para pintar el fondo del control.
En Windows y en MFC anteriores a la versión 4.0, la ventana principal, a menudo un cuadro de diálogo, es responsable de la gestión de estos mensajes. Esto significa que el código para controlar el mensaje debe ser de clase de la ventana principal y que tiene que ser duplicados en cada clase que necesita para manejar ese mensaje. En el caso anterior, cada cuadro de diálogo que quería controles con fondos personalizados tendría que manejar el mensaje de notificación de control de color. Sería mucho más fácil de reutilizar el código si se puede escribir una clase de control que podría manejar su propio color de fondo.
En MFC 4.0, todavía funciona el antiguo mecanismo — windows primario pueden gestionar los mensajes de notificación. Además, sin embargo, MFC 4.0 facilita reutilización proporcionando una característica llamada "mensaje de reflexión" que permite a estos mensajes de notificación para manejarse en la ventana de control de niño o en la ventana principal, o en ambos. En el ejemplo de color de fondo de control, puede escribir ahora una clase de control que establece su propio color de fondo por controlar el mensaje WM_CTLCOLOR reflejado — todo sin depender de los padres. (Tenga en cuenta que ya se implementa reflexión de mensajes MFC, no por Windows, la clase de ventana principal debe derivarse de CWnd para reflexión de mensajes para trabajar).
Versiones anteriores de MFC hicieron algo parecido a la reflexión de mensajes proporcionando funciones virtuales para unos mensajes, tales como mensajes para cuadros de lista dibujado por el propietario (WM_DRAWITEMy así sucesivamente). El nuevo mecanismo de reflexión de mensaje es generalizada y consistente.
Reflexión de mensajes es compatible con el código escrito para las versiones de MFC anteriores a la 4.0.
Si ha proporcionado un controlador para un mensaje específico o para un rango de mensajes, en clase de la ventana de su padre, anulará reflejan controladores de mensajes para el mismo mensaje de siempre no llamar a la función de controlador de clase base en su propio controlador. Por ejemplo, si manejar WM_CTLCOLOR en la clase de cuadro de diálogo, su manejo anulará cualquier controlador de mensaje reflejado.
Si, en la clase de ventana principal, proporciona un controlador para un mensaje WM_NOTIFY específico o un rango de mensajes WM_NOTIFY , se llamará el controlador sólo si el control de niño enviar esos mensajes no tiene un controlador de mensaje reflejado a través de ON_NOTIFY_REFLECT(). Si utiliza ON_NOTIFY_REFLECT_EX() en su mapa de mensajes, su controlador de mensaje puede o no puede permitir la ventana primaria manejar el mensaje. Si el controlador devuelve TRUE, el mensaje será tratado por el padre, mientras una llamada que devuelve que falso no permite el padre manejarlo. Tenga en cuenta que el mensaje reflejado es manejado antes el mensaje de notificación.
Cuando se envía un mensaje WM_NOTIFY , el control se ofrece la primera oportunidad para manejarlo. Si se envía cualquier otro mensaje reflejado, la ventana primaria tiene la primera oportunidad de manejarlo y el control recibirá el mensaje reflejado. Para ello, será necesario una función de controlador y una entrada correspondiente en el mapa de mensajes de clase del control.
La macro de mapa de mensajes para mensajes reflejados es ligeramente diferente para notificaciones regulares: tiene _REFLECT anexado a su nombre habitual. Por ejemplo, para manejar un mensaje WM_NOTIFY en el padre, utilice la macro ON_NOTIFY en el mapa de mensajes de los padres. Para manejar el mensaje reflejado en el control secundario, utilice la macro ON_NOTIFY_REFLECT en el mapa de mensajes de control secundario. En algunos casos, los parámetros son distintos, así. Tenga en cuenta que ClassWizard normalmente puede agregar las entradas de mapa de mensajes para usted y proporcionar implementaciones de esqueleto de función con parámetros correctos.
Ver TN061: ON_NOTIFY y mensajes WM_NOTIFY para obtener información sobre el nuevo mensaje WM_NOTIFY.
Las entradas de mapa de mensajes y prototipos de función de controlador de mensajes reflejados
Para manejar un mensaje de notificación de control reflejada, utilice el mapa de mensajes macros y prototipos de función enumeradas en la tabla siguiente.
ClassWizard normalmente puede agregar estas entradas de mapa de mensajes para usted y proporcionar implementaciones de esqueleto de función. Ver definir un controlador de mensajes para un mensaje reflejado en la Guía del programador de Visual C++ para obtener información acerca de cómo definir los controladores de mensajes reflejados.
Para convertir el nombre del mensaje a nombre de la macro reflejada, anteponer ON_ y anexar _REFLECT. Por ejemplo, WM_CTLCOLOR se convierte en ON_WM_CTLCOLOR_REFLECT. (Para ver los mensajes que pueden reflejarse, hacer la conversión opuesta en las entradas de macro en el cuadro siguiente).
Las tres excepciones a la regla anterior son los siguientes:
En cada uno de estos casos especiales, debe especificar el nombre de la función de miembro de controlador. En los demás casos, debe utilizar el nombre estándar para la función de controlador.
El significado de los parámetros y valores devueltos por las funciones están documentados bajo el nombre de la función o el nombre de la función con el antepone. Por ejemplo, CtlColor se documenta en OnCtlColor. Varios controladores de mensaje reflejado necesitan menos parámetros que los controladores similares en una ventana primaria. Sólo coinciden con los nombres en la tabla siguiente con los nombres de los parámetros formales en la documentación.
| Entrada del mapa | Prototipo de función |
| ON_CONTROL_REFLECT ( wNotifyCode, memberFxn ) | void afx_msgmemberFxn ( ); |
| ON_NOTIFY_REFLECT ( wNotifyCode, memberFxn ) | void afx_msgmemberFxn(NMHDR * pNotifyStruct, LRESULT * resultado ); |
| ON_UPDATE_COMMAND_UI_REFLECT ( memberFxn ) | void afx_msgmemberFxn(CCmdUI * pCmdUI ); |
| ON_WM_CTLCOLOR_REFLECT) | afx_msg HBRUSH CtlColor (CDC * pDC, UINT nCtlColor ); |
| ON_WM_DRAWITEM_REFLECT) | afx_msg anular DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct ); |
| ON_WM_MEASUREITEM_REFLECT) | afx_msg anular MeasureItem (LPMEASUREITEMSTRUCT lpMeasureItemStruct ); |
| ON_WM_DELETEITEM_REFLECT) | afx_msg anular DeleteItem (LPDELETEITEMSTRUCT lpDeleteItemStruct ); |
| ON_WM_COMPAREITEM_REFLECT) | afx_msg int CompareItem (LPCOMPAREITEMSTRUCT lpCompareItemStruct ); |
| ON_WM_CHARTOITEM_REFLECT) | afx_msg int CharToItem (UINT nKey, UINT nIndex ); |
| ON_WM_VKEYTOITEM_REFLECT) | afx_msg int VKeyToItem (UINT nKey, UINT nIndex ); |
| ON_WM_HSCROLL_REFLECT) | afx_msg anular HScroll (UINT nSBCode, UINT FNCO ); |
| ON_WM_VSCROLL_REFLECT) | afx_msg anular VScroll (UINT nSBCode, UINT FNCO ); |
| ON_WM_PARENTNOTIFY_REFLECT) | afx_msg void ParentNotify (UINT mensaje, LPARAM lParam ); |
Las macros ON_NOTIFY_REFLECT y ON_CONTROL_REFLECT tienen variaciones que permiten más de un objeto (como el control y su padre) para controlar un mensaje determinado.
| Entrada del mapa | Prototipo de función |
| ON_NOTIFY_REFLECT_EX ( wNotifyCode, memberFxn ) | afx_msg BOOLmemberFxn(NMHDR * pNotifyStruct, LRESULT * resultado ); |
| ON_CONTROL_REFLECT_EX ( wNotifyCode, memberFxn ) | afx_msg BOOLmemberFxn ( ); |
Mensajes de control de reflejo: Un ejemplo de un control reutilizable
Este sencillo ejemplo crea un control reutilizable llamado CYellowEdit . El control funciona igual que un control de edición normal excepto que muestra texto en negro sobre fondo amarillo. Sería fácil agregar funciones miembro que permitirían el CYellowEdit control para mostrar diferentes colores.
Para probar este ejemplo, realice los siguientes pasos:
Debe tener una aplicación para desarrollar el control reutilizable. Si no tienes una aplicación existente para utilizar, crear una aplicación basada en el diálogo mediante el Asistente para aplicaciones.
CYellowEdit basado en CEdit. Deje activada la casilla de "Agregar a la Galería de componentes".CYellowEdit clase. Los dos primeros serán variables COLORREF para mantener el color del texto y el color de fondo. El tercero será un objeto CBrush que contendrá el pincel para pintar el fondo. El objeto CBrush le permite crear pincel una vez, simplemente la referencia después de eso y para destruir el pincel automáticamente cuando el CYellowEdit control es destruida.CYellowEdit::CYellowEdit()
{
m_clrText = RGB (0, 0, 0);
m_clrBkgnd = RGB (255, 255, 0);
m_brBkgnd.CreateSolidBrush (m_clrBkgnd);
}
CYellowEdit clase. Tenga en cuenta que el signo igual delante del nombre del mensaje en la lista de mensajes que puede manejar indica que el mensaje se refleja. Esto se describe en definir un controlador de mensajes para un mensaje reflejado en la Guía del programador de Visual C++.ClassWizard agrega la siguiente función de macro y esqueleto de mapa de mensajes para usted:
ON_WM_CTLCOLOR_REFLECT()
/ / Nota: otro código será entre....
HBRUSH CYellowEdit::CtlColor(CDC* pDC, UINT nCtlColor) {
/ / TODO: cambiar los atributos de la DC aquí
/ / TODO: devolver un pincel no NULL si el
/ / controlador del padre no debe llamarse
devolver NULL;
}
pDC-gt;SetTextColor (m_clrText); / / texto
pDC - > SetBkColor (m_clrBkgnd); / / bkgnd de texto
Return m_brBkgnd; / / ctl bkgnd
CYellowEdit control en archivo de encabezado del cuadro de diálogo.CYellowEdit clase a otros proyectos de control.&Notas técnicas por número |nbsp; Notas técnicas por categoría