el Guille, la Web del Visual Basic, C#, .NET y más...

Cambiando el comportamiento predefinido de un control (II)

Heredando el nuevo control

 

Autor: RFOG (MVP de Visual C++)
Publicado: 14/Jul/2010
Actualizado: 14/Jul/2010

Siguiendo con el texto del mes pasado, ahora nos toca heredar nuestro control a partir del que Visual Studio nos ha colocado por defecto en el cuadro de diálogo.


elGuille.hosting: La oferta recomendada:
.NET 2.0, SQL Server, 1200MB, 10GB transf. por 9.95 Euros al mes



 

Introducción:

Siguiendo con el texto del mes pasado, ahora nos toca heredar nuestro control a partir del que Visual Studio nos ha colocado por defecto en el cuadro de diálogo.

Pero antes de heredar debemos crearnos una variable DDX para el intercambio entre la clase que representa el diálogo y el propio diálogo. Para ello hacemos clic con el botón derecho del ratón sobre el control de lista en la plantilla y seleccionamos “Add Member Variable”. Le vamos a dar el nombre de “c_lb”:

mfc08_01.jpg

Si nos fijamos en “Variable Type” veremos que la clase que representa al control se llama CVSListBox: ya sabemos de quién heredar. También podemos verlo en el fichero cabecera del diálogo:

public:
       CVSListBox c_lb;

 

Una vez conocemos la clase, creamos un nuevo par de ficheros con nuestra herencia. Podemos hacerlo a mano o con el asistente para clase nueva. Si lo hacemos con el asistente, nos ponemos en el nombre del proyecto en el Explorador de Soluciones y con el botón derecho del ratón elegimos Add -> Class. Se nos abre una ventana y elegimos “MFC Class”. Entonces se nos abre la siguiente ventana, que tiene el único cometido de elegir la clase base del desplegable y dar el nombre de la nuestra:

mfc08_02.jpg

Al aceptar, el IDE nos crea los ficheros y el esqueleto de la clase. En nuestro caso ha añadido dos nuevos ficheros con los nombres de MyListbox.h y MyListbox.cpp, que contienen el interfaz y el cuerpo de los nuevos métodos y ha insertado las macros y otras parafernalias que son necesarias a la hora que nuestras clases formen parte inherente a MFC.

Ahora tan solo nos queda ir al fichero cabecera del diálogo (en nuestro caso es cambiar_controlDLG.h) y sustituir el tipo de “c_lb” por el nuestro:

public:
       CMyVSListbox c_lb;
};

 

También tenemos que incluir el fichero cabecera para la clase Ccambiar_contolDLG sepa qué es CMyVSListbox:

#pragma once
#include "afxvslistbox.h"
#include "MyVSListbox.h"

// Ccambiar_controlDlg dialog
class Ccambiar_controlDlg : public CDialogEx
{
// Construction
public:
       Ccambiar_controlDlg(CWnd* pParent = NULL);     // standard constructor

// Dialog Data
       enum { IDD = IDD_CAMBIAR_CONTROL_DIALOG };

      
protected:
       virtual void DoDataExchange(CDataExchange* pDX);      // DDX/DDV support


// Implementation
protected:
       HICON m_hIcon;

       // Generated message map functions
       virtual BOOL OnInitDialog();
       afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
       afx_msg void OnPaint();
       afx_msg HCURSOR OnQueryDragIcon();
       DECLARE_MESSAGE_MAP()

public:
       CMyVSListbox c_lb;
};

 

Si compilamos y ejecutamos, el programa funciona igual que antes, pero ahora el cuadro de lista es nuestro cuadro de lista, y en subsiguientes entradas iremos viendo cómo cambiar el comportamiento.

Si os dais cuenta, la biblioteca MFC entiende de este tipo de sustituciones, y si abrimos el diálogo con el editor de diálogos de Visual Studio, veremos que seguimos teniendo el control de lista exactamente igual que si fuera el original y no el nuestro.

Esto tiene una explicación muy sencilla: en la plantilla de diálogo, el control sigue siendo el mismo. Para quien no lo sepa, los cuadros de diálogo de MFC (y de Win32) vienen definidos en un lenguaje propio que Microsoft inventó con la salida de la primera herramienta de desarrollo para Windows: los ficheros de recursos y su terminología. Si queréis ver dónde y cómo se almacena todo esto, id al fichero “cambiar_control.rc” en el Explorador de Soluciones y seleccionad “View Code” con el botón derecho del ratón.

Ahí veréis un fichero de texto con una serie de instrucciones más o menos coherentes. Aunque hubo una época en la que había que escribir todo eso a mano, compilar, ver el resultado, volver a cambiar, y repetir, hace muchísimos años que, salvo excepciones o para cambios rápidos, todas las herramientas de desarrollo para Windows y C/C++ suelen llevar su editor visual e integrado.

En el caso que nos ocupa, el cuadro de diálogo principal queda como:

IDD_CAMBIAR_CONTROL_DIALOG DIALOGEX 0, 0, 320, 200
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
CAPTION "cambiar_control"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
    DEFPUSHBUTTON   "OK",IDOK,209,179,50,14
    PUSHBUTTON      "Cancel",IDCANCEL,263,179,50,14
    CTEXT           "TODO: Place dialog controls here.",IDC_STATIC,10,96,300,8
    CONTROL         "",IDC_MFCVSLISTBOX1,"MfcVSListBox",WS_TABSTOP,7,7,125,186
END

 

Si os fijáis en la penúltima línea, “CONTROL” etc. define el cuadro de lista. La cadena “MfcVSListBox” indica que clase de control es, de modo que tanto el IDE como luego en ejecución, se sabrá qué pintar.

Luego, el compilador de recursos cogerá ese fichero y generará una serie de metadatos que irán insertados en el ejecutable y que, al igual que la reflexión en .NET, construirán el diálogo. La ventaja frente a .NET es que este proceso es prácticamente inmediato incluso con cuadros de diálogo con cientos y cientos de controles. Digamos que este método es el padre de XAML, que es mucho más potente.

Pues bien, lo que hace aquí MFC es que en tiempo de ejecución, al asignar la clase que se corresponda con ese control, pondrá nuestra clase en lugar de CVSListbox al modo que se utilizan clases virtuales: se instancia al padre pero se llama al constructor del hijo, todo ello de forma automática y transparente para nosotros.

 

Código fuente:

El lector tiene el código fuente de esta entrada disponible en el fichero:
MFC_08_cambiar_control_01.zip


(MD5 checksum: 1839CB081501DDD7FEB847F8B4238CEE)

 

 

 


Ir al índice de los artículos de RFOG en el sitio del Guille




Haz tu donativo a este sitio con PayPal
 

Busca en este sitio con Google
 
Google

La fecha/hora en el servidor es: 28/03/2024 11:28:30

La fecha actual GMT (UTC) es: 

©Guillermo 'guille' Som, 1996-2024