Captura de mensajes en MFC: ¿cuál es la diferencia?
Pregunta
Me preguntaba cuál era (si hubiera) la diferencia entre las siguientes dos trampas de mensajes en MFC para la función, OnSize (..).
1 - A través del mapa del mensaje:
BEGIN_MESSAGE_MAP(CClassWnd, CBaseClassWnd)
...
ON_WM_SIZE()
..
END_MESSAGE_MAP()
2 - Vía afx_message:
afx_msg type OnSize(...);
Parece que se usan indistintamente, ¿cuál debería usarse o depende de otros factores?
Solución
Ambas partes son necesarias para agregar un controlador de mensajes a una clase. El mapa de mensajes debe declararse dentro de su clase, junto con las declaraciones para cualquier función de controlador de mensajes (por ejemplo, OnSize
).
class CClassWnd : public CBaseClassWnd {
...
afx_msg void OnSize(UINT nType, int cx, int cy);
DECLARE_MESSAGE_MAP
};
afx_msg
es solo una macro de marcador de posición vacía: en realidad no hace nada, pero siempre se incluye por convención.
El mapa de mensajes se define luego en el archivo .cpp de la clase:
BEGIN_MESSAGE_MAP(CClassWnd, CBaseClassWnd)
ON_WM_SIZE()
END_MESSAGE_MAP()
Estas macros generan una tabla de búsqueda para la clase que permite que los mensajes recibidos por la ventana se envíen a las funciones de controlador correspondientes. La macro ON_WM_SIZE
permite que los parámetros de mensaje wParam
y lParam
en el mensaje WM_SIZE
se decodifiquen en valores más significativos para la función del controlador de mensajes ( nType
, cx
y cy
en este caso). MFC proporciona macros para la mayoría de los mensajes de ventana ( WM_LBUTTONDOWN
, WM_DESTROY
, etc.).
Puede encontrar más información sobre cómo funcionan los mapas de mensajes en MFC aquí en MSDN.
Otros consejos
afx_msg es solo una macro vacía, básicamente está ahí para denotar que el método es un controlador de mensajes MFC para facilitar la lectura. Incluso con afx_msg allí todavía es necesario tener una entrada en el mapa de mensajes.
Algunos de los mensajes de Windows ya son manejados por MFC , por lo que en estos casos puede evitar agregar solo el método a su clase derivada.
Por ejemplo, la clase CWnd (al igual que muchas otras clases MFC) ya asigna algunos mensajes de Windows en su mapa de mensajes (es decir, ON_WM_DRAWITEM , ON_WM_MEASUREITEM , ON_WM_ENTERIDLE etc., etc.).
Pero cualquier otro mensaje que MFC aún no haya asignado tendrá que tener un método de clase y una entrada en el mapa de mensajes para que funcione.