Introducción:
Cómo variar el comportamiento de un control MFC mediante herencia.
Hay veces que algunos controles de MFC no funcionan como nos gustaría y
encima no tienen opciones ni posibilidad para cambiar su comportamiento a
nuestro placer. En estas dos entradas os voy a explicar cómo heredar un
control y cómo poner el nuestro en lugar del original.
Para ello vamos a utilizar un proyecto con un cuadro de diálogo como
ventana principal tal y como queda después de usar el asistente sin cambiar
otra opción que la elección de “Dialog Based” en la primera pantalla. Y
luego dejamos caer un MFC VSListBox, que es una especie de control de lista
con esteroides, con botones para crear, editar y borrar elementos. Nuestro
proyecto quedaría en el editor de cuadros de diálogo más o menos como la
imagen:
Compilamos y ejecutamos y jugamos un poco con él. Ahora que hemos visto
todas sus posibilidades, cerramos la aplicación y nos vamos a las
Propiedades del cuadro de diálogo. Al seleccionar el list box y cambiar a la
vista de mensajes y eventos ¡nos damos cuenta de que está vacío! Si tenemos
Visual Studio 2010 y abrimos el Class Wizard tampoco vemos nada relevante.
¿Cómo es posible que no tengamos eventos para cuando cambia uno
seleccionado o cuando se crea o se destruye? Pues sí, hijo, sí, a veces
Microsoft la caga de esta manera tan completa. A la lumbrera que diseñó el
control habría que ponerlo a pastorear cabras, pero no muchas, no sea que se
le escapen.
Pero no hay mal que por bien no venga: eso me permite a mí contaros todo
esto, dividido en dos partes (Y también para pillarle a Microsoft una fuga
de memoria en MFC, pero de eso hablaré en otro momento).
Herencia de componentes
El componente MFC VSListBox es lo que se llama un componente compuesto,
que no es más que una serie de ventanas unidas con un comportamiento común
dentro de una sola clase y que se exporta (ignoro cómo) para que esté
disponible como un elemento más de cuadro de diálogo. Lo que ha ocurrido
aquí es que no se han exportado eventos aunque sí propiedades, por lo que
debemos heredar nuestra propia clase de la de MFC VSListBox.
El hecho de heredar supone que tenemos acceso a la parte pública y a la
protegida del control (si heredamos de forma pública), y si ha sido diseñado
correctamente, nos facilita mucho la tarea de trabajar con él, que no es el
caso, y es por dicha dificultad por lo que lo he elegido de entre otros más
sencillos y clásicos.
Existen tres maneras diferentes de cambiar el comportamiento de un
control (ya sea compuesto o no) cuando heredamos:
- Acceso a mensajes y eventos por reflexión. Igual que creamos un mapa
de mensajes para capturar los mensajes de los controles hijos en una
clase (sea de cuadro de diálogo o no), también podemos hacerlo sobre la
propia clase que representa el control y atender nosotros a los mensajes
que debería atender el contenedor o propietario. Esto se realiza con las
macros de reflexión, que veremos en otra entrada.
- Sobreescritura de métodos virtuales. Para ello la clase padre ha de
estar preparada para ello. El caso más típico es el InitInstance()
de CWinApp y el OnInitDialog() de CDialog. La
clase padre espera que la hija sobrescriba esos métodos para dar
funcionalidad. En principio no nos importan de dónde vengan esos
métodos, lo que importa es que debemos sobrescribirlos, aunque
normalmente suelen venir de mensajes de ventana de Win32 tan importantes
que si no estuvieran capturados el programa no funcionaría bien.
- Creación de mensajes nuevos para aumentar las características de un
control. El origen de esos mensajes tampoco tiene mucha importancia, lo
que sí debemos comprender es por qué se han creado.
En siguientes entregas iremos viendo cómo hacer todo esto.
Ir al índice de los artículos de RFOG en el
sitio del Guille