Capítulo 51 Control Tooltip

Tooltip
Tooltip

Los controles Tooltip son pequeñas ventanas que aparecen sobre otros controles, generalmente llamados herramientas, y que desaparecen al cabo de un tiempo corto. Normalmente se usan para mostrar pistas o ayudas al usuario sobre la tarea asignada al control, o para mostrar el texto completo de un ítem de una lista o árbol cuando parte de ese texto queda oculto tras el borde del control.

Cuando veamos las barras de herramientas veremos que se trata de conjuntos de botones, cada uno de los cuales indica la acción mediante un icono. Esto hace que a menudo no sea evidente qué hace cada herramienta. En estos casos, los tooltips serán especialmente útiles.

De nuevo estamos ante controles estáticos, en el sentido de que no sirven para obtener datos por parte del usuario, sino para mostrarle información.

De forma similar a lo que pasa con las listas de imágenes, veremos que estos controles se usan conjuntamente con otros que veremos en próximos capítulos, como list-views, tree-views, barras de herramientas, etc.

Creación de tooltip

Los controles tooltip se crean usando la función CreateWindowEx, indicando como tipo de ventana la constante TOOLTIPS_CLASS, el estilo extendido WS_EX_TOOLWINDOW, al menos el estilo WS_POPUP, más los estilos específicos de controles tooltip que queramos.

En realidad, los controles tooltip siempre tienen los estilos WS_EX_TOOLWINDOW y WS_POPUP, aunque no se especifiquen de forma explícita.

Para las coordenadas y dimensiones usaremos la constante CW_USEDEFAULT, puesto que la posición dependerá de la posición del ratón y del control al que pertenezca el tooltip, y su tamaño del contenido que le asignemos.

           hwndTip = CreateWindowEx(WS_EX_TOOLWINDOW, TOOLTIPS_CLASS, NULL,
                              WS_POPUP | TTS_ALWAYSTIP |  TTS_BALLOON,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              hwnd, NULL,
                              hInstance, NULL);

Inicialmente, el control tooltip estará oculto, por eso no especificamos el estilo WS_VISIBLE. De todos modos, aunque lo indiquemos, no se activará.

También es conveniente hacer que la ventana tooltip sea la "topmost", de modo que nunca sea ocultada por otras ventanas o controles:

           SetWindowPos(hwndTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);

Es convieniente conservar el manipulador de ventana del tooltip en una variable estática, sobre todo si necesitamos enviarle mensajes después de crear la ventana.

Esto es necesario porque al tratarse de una ventana con el estilo WS_POPUP, el décimo parámetro se trata como un manipulador de menú, y no como un identificador de control, por lo que debe ser cero. Esto hace que no podamos enviarle mensajes usando SendDlgItemMessage, y necesitarmos el manipulador de ventana del tooltip.

Como con el resto de los controles comunes, es necesario asegurarse de que la DLL ha sido cargada mediante una llamada a la función InitCommonControls.

Estilos

Los controles tooltip tienen varios estilos propios que controlan varios aspectos gráficos:

  • TTS_ALWAYSTIP: el control tooltip se activa aunque la ventana padre no tenga el foco.
  • TTS_BALLOON: tooltip en forma de globo, con las esquinas redondeadas y un saliente que apunta al control al que pretenece.
  • TTS_CLOSE: añade un botón de cerrar, es necesario que también esté activo el estilo TTS_BALLOON y que se haya asignado un título, además deben estar activos los estilos visuales.
  • TTS_NOANIMATE: desactiva la animación inicial del control, que hace que parezca que la ventana se desenrolla.
  • TTS_NOFADE: desactiva la animación final, que hace que la ventana se desvanezca.
  • TTS_NOPREFIX: evita que se eliminen los caracteres '&' y que la cadena se de por terminada cuando se encuentre el primer carácter tabulador.
  • TTS_USEVISUALSTYLE: está relacionado con hiperenlaces, y no lo veremos en este capítulo.

Activar y desactivar tooltips

Por defecto, una vez creado, el tooltip quedará activado, pero podemos desactivarlo y volverlo a activar mediante el mensaje TTM_ACTIVATE, indicando en wParam un valor TRUE para activarlo o FALSE para desactivarlo.

    SendMessage(hwndTip, TTM_ACTIVATE, (WPARAM)TRUE, 0);

Cambios de color

Es posible modificar los colores del fondo y de los caracteres de un control tooltip, usando los mensaje TTM_SETTIPBKCOLOR y TTM_SETTIPTEXTCOLOR, respectivamente. En ambos casos, el color deseado se especifica en el parámetro wParam.

    SendMessage(hwndTip, TTM_SETTIPTEXTCOLOR, (WPARAM)RGB(255,0,0), 0);
    SendMessage(hwndTip, TTM_SETTIPBKCOLOR, (WPARAM)RGB(240,255,255), 0);

Hay que tener en cuenta que, como pasaba con las barras de progreso, si se activan los controles visuales, estos mensajes no tendrán efecto, y se usarán siempre los colores del tema.

Asignar título e icono

A cada ventana tooltip se le puede asociar un icono y un título. Hay que asignar ambos o ninguno, los dos van unidos, aunque el icono que indiquemos puede ser nulo.

Para hacerlo disponemos del mensaje TTM_SETTITLE, en el que usaremos el parámetro wParam para indicar el icono, y el parámetro lParam para indicar el texto del título:

           HICON hIcon = LoadIcon(hInstance, "Icono");
           SendMessage(hwndTip, TTM_SETTITLE, (WPARAM)hIcon, (LPARAM)"Ejemplo 087");
           DestroyIcon(hIcon);

Como icono podemos usar uno de los iconos predefinidos, para lo que disponemos de varias constantes:

  • TTI_NONE: Sin icono.
  • TTI_INFO: Icono de informacion.
  • TTI_WARNING: Icono de aviso.
  • TTI_ERROR: Icono de error.
  • TTI_INFO_LARGE: Icono de información grande.
  • TTI_WARNING_LARGE: Icono de aviso grande.
  • TTI_ERROR_LARGE: Icono de error grande.

Los iconos grandes sólo están disponibles si se activan los estilos visuales, con el estilo clásico sólo se pueden especificar los iconos pequeños, o TTI_NONE.

Si se activan los estilos visuales, en wParam podemos especificar cualquier icono, mediante su manipulador.

Nota: la versión actual de "commctrl.h" cuando escribo este capítulo tiene algunos errores con respecto a este tema concreto. No están definidas las constantes "TTI_", ni el mensaje "TTM_SETTITLE". Para poder utilizar títulos de tooltips en nuestros programas deberemos añadir las siguientes definiciones:

#ifndef TTM_SETTILE
#ifdef UNICODE
#define TTM_SETTITLE TTM_SETTITLEW
#else
#define TTM_SETTITLE TTM_SETTITLEA
#endif
#endif

#ifndef TTI_NONE
// ToolTip Icons (Set with TTM_SETTITLE)
#define TTI_NONE                0
#define TTI_INFO                1
#define TTI_WARNING             2
#define TTI_ERROR               3
#if (_WIN32_WINNT >= 0x0600)
#define TTI_INFO_LARGE          4
#define TTI_WARNING_LARGE       5
#define TTI_ERROR_LARGE         6
#endif  // (_WIN32_WINNT >= 0x0600)
#endif

Limitar anchura

Podemos limitar la anchura máxima del control tooltip, de modo que el texto que incluye se fragmente en distintas líneas si supera la anchura establecida. Para limitar la anchura máxima se usa el mensaje TTM_SETMAXTIPWIDTH, indicando el lParam la anchura máxima en pixels, o -1 para permitir cualquier anchura.

        SendMessage(hwndTip, TTM_SETMAXTIPWIDTH, 0, 150);