Capítulo 39 Control Edit avanzado

En este capítulo, y en los siguientes vamos a comentar con más detalles los controles básicos que ya hemos visto previamente. Veremos algunas características más avanzadas de cada uno, los mensajes de notificación, y los mensajes que aún no conocemos de cada uno.

Empezaremos por el control edit, y veremos todo lo que no se explicó en el capítulo 7.

Insertar controles edit durante la ejecución

En general, el sistema que vamos a comentar puede ser aplicado a cualquier control, aunque veremos ejemplos para cada caso.

En realidad, un control no es otra cosa que una ventana, en el caso del control edit, se trata de una ventana de la clase "EDIT". Como ventana que es tiene su propio procedimiento de ventana, y por supuesto, se pueden crear esta clase de ventanas usando las funciones CreateWindow y CreateWindowEx.

Este sistema nos permite insertar controles en cualquier ventana o cuadro de diálogo, en lugar de usar siempre cuadros de diálogo y ficheros de recursos para insertar los controles. Cuando las aplicaciones sean sencillas será frecuente que nos baste una ventana para realizar todas las entradas y salidas.

Por supuesto, la posibilidad de insertar controles durante la ejecución nos proporciona más flexibilidad, y mayor control sobre la aplicación en ciertas circunstancias, por ejemplo, evitar que los cuadros de diálogo se puedan editar usando herramientas de edición de recursos.

Veamos un ejemplo de cómo insertar un control de edición en una ventana:

    HWND hctrl;
...
        case WM_CREATE:
           hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
           /* Insertar control Edit */
           hctrl = CreateWindowEx(
              0,
              "EDIT",          /* Nombre de la clase */
              "",              /* Texto del título, no tiene */
              ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, /* Estilo */ 
              36, 20,          /* Posición */
              120, 20,         /* Tamaño */
              hwnd,            /* Ventana padre */
              (HMENU)ID_TEXTO, /* Identificador del control */
              hInstance,       /* Instancia */
              NULL);           /* Sin datos de creación de ventana */ 
           /* Inicialización de los datos de la aplicación */
           SetDlgItemText(hwnd, ID_TEXTO, "Inicial");
           SetFocus(hctrl);
           return 0;

Como vemos, usamos los mismos valores que en el fichero de recursos: identificador, clase de ventana (en este caso "EDIT"), estilo, posición y dimensiones.

El identificador del control se suministra a través del parámetro hMenu, por lo que será necesario hacer un casting del identificador al tipo HMENU.

Ahora será nuestro procedimiento de ventana el encargado de procesar los mensajes procedentes del control. Recordemos que en los ejemplos que hemos visto hasta ahora esto lo hacía el procedimiento de diálogo.

Cambiar la fuente de un control edit

Veremos a continuación algunas formas de personalizar los controles edit.

Al insertar los controles edit en un cuadro de diálogo, usando el fichero de recursos, podemos especificar la fuente que queremos usar, pero al insertarlo directamente mediante la función CreateWindow o CreateWindowEx, Windows siempre usa la fuente del sistema por defecto.

Esto afecta al aspecto estético de nuestros controles, (la verdad es que la fuente del sistema es bastante fea), y una de las ventajas de las aplicaciones gráficas es precisamente poder elegir el aspecto que queremos que tengan.

Pero hay una solución, es posible modificar la fuente de un control edit enviando un mensaje WM_SETFONT. El lugar apropiado es, por supuesto, al procesar el mensaje WM_INITDIALOG, cuando se trate de cuadros de diálogo, o al procesar el mensaje WM_CREATE, cuando se trate de ventanas.

En el parámetro wParam pasamos un manipulador de fuente, y usaremos la macro MAKELPARAM para crear un valor LPARAM, en el que especificaremos la opción de repintar el control, que se almacena en la palabra de menor peso de LPARAM.

Esto nos permite modificar la fuente durante la ejecución, reflejando los cambios en pantalla.

   static HFONT hfont;
...
           hfont = CreateFont(24, 0, 0, 0, 300,
              FALSE, FALSE, FALSE, DEFAULT_CHARSET,
              OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
              PROOF_QUALITY, DEFAULT_PITCH | FF_ROMAN,
              "Times New Roman");
           SendMessage(hctrl, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(TRUE, 0));
...
        case WM_DESTROY:
           DeleteObject(hfont);
...

En el caso de crear una fuente especial para nuestros controles, debemos recordar destruirla cuando ya no sea necesaria, generalmente al destruir la ventana.

Por supuesto, también podemos usar una fuente de stock:

           hfont = (HFONT)GetStockObject( DEFAULT_GUI_FONT );
           SendMessage(hctrl, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(TRUE, 0));

Cambiar los colores de un control edit

Podemos personalizar más nuestros controles edit, cambiando los colores del texto y del fondo. Para ello deberemos procesar el mensaje WM_CTLCOLOREDIT.

Este mensaje se envía a la ventana padre del control justo antes de que el sistema lo vaya a dibujar, y nos permite cambiar los colores del texto y fondo. Para ello nos suministra en el parámetro wParam un manipulador del contexto de dispositivo del control, y en lParam un manipulador del control, mediante el cual podemos saber a qué control concreto se refiere el mensaje.

El valor de retorno, cuando se procesa este mensaje, debe ser un manipulador de pincel con el color de fondo del control.

    static HBRUSH pincel;
    HWND hcrtl;

    switch (msg)                  /* manipulador del mensaje */
    {
        case WM_CREATE:
           hcrtl = CreateWindowEx(...);
           pincel = CreateSolidBrush(RGB(0,255,0));
           SetFocus(hcrtl);
           return 0;
        case WM_CTLCOLOREDIT:
           SetBkColor((HDC)wParam, RGB(0,255,0));
           SetTextColor((HDC)wParam, RGB(255,255,255));
           return (LRESULT)pincel;
        case WM_DESTROY:
           DeleteObject(pincel);
           PostQuitMessage(0);    /* envía un mensaje WM_QUIT a la cola de mensajes */
           break;
...

Ejemplo 49


  Nombre Fichero Fecha Tamaño Contador Descarga
D Ejemplo 49 win049.zip 2007-03-15 3104 bytes 439