Capítulo 43 Control combo box avanzado

Seguimos con el repaso de los controles más comunes del API de Window.

En el capítulo 11 vimos cómo usar de una forma básica los combo boxes. También vimos que estos controles son la combinación de un control edit o un control de texto estático y un list box, así como el modo de crearlos a partir de un fichero de recursos, de inicializarlos y de leer el valor de su selección.

En este capítulo veremos mucho más sobre ellos, cómo personalizarlos, qué estilos pueden tener, sus mensajes de notificación, etc.

Ya que son la combinación de un control edit (o static) y de un control listbox, estos controles tendrán muchas de las características de los controles de los que se derivan, y por lo tanto, disponen de los equivalentes de algunos de sus estilos, mensajes de notificación y mensajes de control.

Tipos de combo boxes

Ya vimos que existen tres tipos básicos de combo boxes, dependiendo de que se seleccione uno de los tres estilos que los definen:

  • Simple: si se usa el estilo CBS_SIMPLE ComboBox simple
  • Desplegable: (Drop-down) si se usa el estilo CBS_DROPDOWN. La lista se puede desplegar mediante el teclado mediante F4, o pulsando sobre el icono de la flecha abajo. El texto de entrada se puede introducir en la zona de edición, o se puede elegir un valor de la lista. La siguiente imagen muestra el mismo combo box con la lista plegada y desplegada. ComboBox desplegable
  • Lista desplegable: (Drop-down list) si se usa el estilo CBS_DROPDOWNLIST. Al igual que en el tipo desplegable, la lista se puede desplegar mediante el teclado o el ratón, pero en este caso, el texto sólo se puede elegir entre los valores de la lista. Se puede usar el teclado para elegir el elemento de la lista, tecleando el principio de la cadena. La imagen siguiente muestra uno de estos controles con la lista plegada y desplegada. ComboBox lista desplegable

Insertar controles combo box durante la ejecución

No hay nada nuevo en este tema, del mismo modo que hemos visto para los controles anteriormente tratados, también es posible insertar controles combo box durante la ejecución. En este caso tendremos que insertar una ventana de la clase "COMBOBOX". Para insertar el control también usaremos las funciones CreateWindow y CreateWindowEx.

    HWND hctrl;
...
        case WM_CREATE:
           hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
           /* Insertar control Edit */
           hctrl = CreateWindowEx(
              0,
              "COMBOBOX",     /* Nombre de la clase */
              NULL,           /* Texto del título */
              CBS_SIMPLE | 
              WS_VSCROLL | WS_CHILD | WS_VISIBLE | WS_TABSTOP, /* Estilo */
              5, 5,            /* Posición */
              120, 85          /* Tamaño */
              hwnd,            /* Ventana padre */
              (HMENU)ID_COMBO1,/* Identificador del control */
              hInstance,       /* Instancia */
              NULL);           /* Sin datos de creación de ventana */

Como vemos, usamos los mismos valores que en el fichero de recursos: un identificador, la clase de ventana (en este caso "COMBOBOX"), una combinación de estilos, la posición y las dimensiones.

Al igual que en los demás controles, el identificador del control se suministra a través del parámetro hMenu, por lo que será necesario hacer un casting a HMENU.

Cambiar la fuente de un control combo box

En esto tampoco hay novedades, podemos cambiar la fuente de un control combo box mediante un mensaje WM_SETFONT:

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

Cambiar colores en combo box

Al tratarse de controles híbridos, formados mediante controles más simples, para cambiar el color de los controles combo box deberemos responder a varios de los mensajes de cambio de color, según la zona que nos interese personalizar.

Así, respondiendo al mensaje WM_CTLCOLORLISTBOX, podremos modificar el color de fondo y el del texto de la parte de la lista.

Mediante el mensaje WM_CTLCOLOREDIT, podremos modificar el color de fondo y del texto de la parte correspondiente al control de edición o estática (según el tipo de combo box).

Por supuesto, en cada caso deberemos retornar con un manipulador de pincel con el color usado para el fondo.

    static HBRUSH pincel, pincel2;
...
        case WM_CREATE:
...
           pincel = CreateSolidBrush(RGB(0,255,0));
           pincel2 = CreateSolidBrush(RGB(0,255,255));
...
        case WM_CTLCOLOREDIT:
           SetTextColor((HDC)wParam, RGB(255,255,0));
           SetBkColor((HDC)wParam, RGB(0,255,255));
           return (LRESULT)pincel2;
        case WM_CTLCOLORLISTBOX:
           SetTextColor((HDC)wParam, RGB(255,0,0));
           SetBkColor((HDC)wParam, RGB(0,255,0));
           return (LRESULT)pincel;
...
        case WM_DESTROY:
...
           DeleteObject(pincel);
           DeleteObject(pincel2);
...

Mensajes de notificación

Entre los mensajes de notificación de los controles combo box, los hay relativos a la parte del control de edición y a la parte de la lista.

Como en todos los casos, los mensajes de notificación se reciben a través de un mensaje WM_COMMAND. En la palabra de menor peso del parámetro wParam se envía el identificador del control. En el parámetro lParam se envía el manipulador del control y el código del mensaje de notificación en la palabra de mayor peso de wParam.

Nota: en el API de Windows 3.x el código del mensaje de notificación se envía en el parámetro lParam. Hay que tener esto en cuenta si se intenta portar código entre estas plataformas.

Cambio en selección de lista

El mensaje de notificación CBN_SELCHANGE se envía a la ventana padre cada vez que la selección en el list box de un combo box vaya a cambiar por una acción del usuario.

Validar selección

El mensaje de notificación CBN_SELENDOK se envía a la ventana padre si después de hacer una selección se cierra la lista. El mensaje CBN_SELENDCANCEL se envía si después de una selección, la lista no se pliega, sino que se cierra el cuadro de diálogo o el foco pasa a otro control.

Estos mensajes sólo se envían a combo boxes que no tengan el estilo CBS_SIMPLE, ya que en el caso de los combo boxes simples, la lista no puede ser cerrada.

Despliegue de lista

El mensaje de notificación CBN_DROPDOWN se envía cada vez que la lista de un combo box es desplegada. De forma simétrica, se envía un mensaje CBN_CLOSEUP cada vez que la lista se pliega de nuevo.

Doble clic

Cada vez que el usuario hace doble clic sobre uno de los elementos del list box de un combo box, se envía un mensaje de notificación CBN_DBLCLK a su ventana padre.

Falta espacio

Si no es posible conseguir memoria para completar una operación sobre el list box, se envía un mensaje de notificación CBN_ERRSPACE.

Modificación

Cada vez que el usuario modifica el texto de la parte del control de edición, primero se actualiza el contenido del control en pantalla, y a continuación se genera un mensaje CBN_EDITCHANGE.

Actualización

Cada vez que el usuario modifica el texto de la parte del control de edición, y antes de que este nuevo texto se muestre en pantalla, Windows envía un mensaje CBN_EDITUPDATE.

Pérdida y recuperación de foco

Cada vez que el usuario selecciona otro control se envía un mensaje de notificación CBN_KILLFOCUS.

Cuando el usuario selecciona un control list box, se envía un mensaje de notificación CBN_SETFOCUS.

Otros estilos para combo box

Entre los estilos también hay es evidente que estos controles son una mezcla de un control de edición o estático con un control de lista. Esto se ve en que hay estilo que sólo afectan a una de las partes o a las dos.

Estilos para la parte de edición

  • CBS_AUTOHSCROLL: cuando el texto que se introduce en la parte del control de edición de un combo box no cabe en el área destinada a mostrarlo, se desplaza automáticamente a la derecha. Si no se activa este estilo, sólo podrá introducirse el texto que cabe dentro de los límites del cuadro de edición.
  • CBS_LOWERCASE: cualquier texto introducido en el control edit del combo box se convierte a minúsculas.
  • CBS_UPPERCASE: cualquier texto introducido en el control edit del combo box se convierte a mayúsculas.

Estilos para la lista

Ya hemos visto antes algunos de estos estilos, pero comentaremos todos de nuevo:

  • CBS_DISABLENOSCROLL: se muestra siempre la barra de scroll vertical del list box, aunque aparece deshabilitada cuando no hay suficientes elementos para llenar la lista. Si no se especifica este estilo, la barra de scroll se oculta, en lugar de deshabilitarse, cuando no hay suficientes elementos en la lista.
  • CBS_HASSTRINGS: como en el caso de los controles list box, este estilo está siempre activo en combo boxes que no tengan el estilo owner-drawn (controles que son actualizados por la ventana padre). Este estilo indica que el control contiene elementos que son cadenas de caracteres. El combo box es el encargado de mantener la memoria y las direcciones de las cadenas, de modo que la aplicación puede usar el mensaje CB_GETLBTEXT para recuperar el texto de un elemento en particular.
  • CBS_NOINTEGRALHEIGHT: especifica que el tamaño de la lista del combo box es exactamente el indicado por la aplicación cuando se creó. Normalmente, Windows cambia el tamaño del combo box para que se muestren líneas completas, y no se corte el texto correspondiente a la última línea de la lista.
  • CBS_SORT: ordena alfabéticamente, de forma automática las cadenas introducidas en la lista.

Ejemplo 71


  Nombre Fichero Fecha Tamaño Contador Descarga
D Ejemplo 71 win071.zip 2007-03-15 3583 bytes 291