Imágenes

Existen tres estilos básicos para crear controles estáticos con imágenes:

  • SS_BITMAP: se mostrará un mapa de bits. Si se hace desde un fichero de recursos, el texto del control corresponde con un recurso de mapa de bits definido en algún lugar del fichero de recursos. Si se inserta directamente en la ventana o diálogo, será necesario asignar un mapa de bits.
  • SS_ICON:se mostrará un icono. Si se hace desde un fichero de recursos, el texto del control corresponde con un recurso de icono definido en algún lugar del fichero de recursos. Si se inserta directamente en la ventana o diálogo, será necesario asignar un icono.
  • SS_ENHMETAFILE: se mostrará un metafichero mejorado. Si se hace desde un fichero de recursos, el texto del control corresponde con un recurso de metafichero definido en algún lugar del fichero de recursos. Si se inserta directamente en la ventana o diálogo, será necesario asignar un metafichero. Noveremos este estilo por ahora, en el futuro estudiaremos los metaficheros y los metaficheros mejorados.

Mensajes para asignar imágenes

Podemos usar el mensaje STM_SETIMAGE para asignar un mapa de bits, un icono, un cursor o un metafichero a un control estático. El parámetro wParam contendrá una constante que indica el tipo de imagen, y el parámetro lParam un manipulador de imagen:

   SendMessage(hctrl, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)bitmap);
   SendMessage(hctrl, STM_SETIMAGE, IMAGE_ICON, (LPARAM)Icono);

De forma simétrica, el mensaje STM_GETIMAGE permite obtener un manipulador de la imagen asociada a un control estático. Igual que antes, el parámetro wParam contendrá una constante que indica el tipo de imagen.

Además, existen otros mensajes equivalentes para controles estáticos con el estilo SS_ICON. Así, el mensaje STM_SETICON permite asignar un icono a un control estático, y el mensaje STM_GETICON recuperar un manipulador del icono actual del control. Estas dos líneas son equivalentes:

   SendMessage(hctrl, STM_SETICON, (WPARAM)Icono, 0);
   SendMessage(hctrl, STM_SETIMAGE, IMAGE_ICON, (LPARAM)Icono);

Modificadores de estilo

Podemos aplicar algunos modificadores de estilo a los tres descritos anteriormente. Si no se aplica ningún modificador, el tamaño del control se calcula a partir del tamaño de la imagen, y se ignora el especificado al crear el control.

  • SS_CENTERIMAGE: si se especifica, el control tendrá el tamaño especificado, el gráfico se mostrará centrado y la parte no usada se rellena con el color del pixel de la esquina superior izquierda de la imagen.
  • SS_REALSIZEIMAGE: cuando se usa, el gráfico se escalará si el tamaño del control aumenta o disminuye, de modo que ocupe toda su área de cliente.
  • SS_RIGHTJUST: hasta la fecha ignoro para qué sirve esta opción. :-)

Modificador de hundido

Todos los estilos anteriores se pueden combinar con un modificador, el estilo SS_SUNKEN, que crea la apariencia de que el control está ligeramente hundido con respecto al resto del área de cliente de la ventana:

modificador SS_SUNKEN

Mensajes de notificación

La clase Static dispone de varios mensajes de notificación, pero para que se envíen se debe activar el estilo SS_NOTIFY. En realidad los controles static no están diseñados para ser interactivos, de modo que esto es algo lógico.

Como en todos los casos, los mensajes de notificación se envían a la ventana padre en la palabra de mayor peso del parámetro wParam, mediante un mensaje WM_COMMAND. Los mensajes de notificación son:

  • STN_CLICKED: se envía cuando el usuario hace clic sobre el control.
  • STN_DBLCLK: se envía cuando el usuario hace soble clic sobre el control.
  • STN_DISABLE: se envía cuando el control es deshabilitado.
  • STN_ENABLE: se envía cuando el control es habilitado.

Por ejemplo:

      case WM_COMMAND:
         switch(LOWORD(wParam)) {
            case ID_EST14:
               switch(HIWORD(wParam)) {
                  case STN_CLICKED:
                     MessageBox(hwnd, "Clic", "Controles estáticos", MB_OK);
                     break;
                  case STN_DBLCLK:
                     MessageBox(hwnd, "Doble clic", "Controles estáticos", MB_OK);
                     break;
                  case STN_DISABLE:
                     MessageBox(hwnd, "Disable", "Controles estáticos", MB_OK);
                     break;
                  case STN_ENABLE:
                     MessageBox(hwnd, "Enable", "Controles estáticos", MB_OK);
                     break;
               }
               break;
         }
         break;

Controles estáticos owner-draw

Los controles estáticos también disponen de un estilo owner-draw.

Para crear un control estático owner-draw se debe activar el estilo SS_OWNERDRAW. De este modo nuestra aplicación se hará cargo de mostrar el control, y seremos los únicos responsables de su aspecto gráfico.

Lo primero es crear el control con el estilo SS_OWNERDRAW:

   HWND hctrl;
...
   hctrl = CreateWindowEx(
      0,
      "STATIC",        /* Nombre de la clase */
      "Texto",         /* Texto del título */
      SS_OWNERDRAW | 
      WS_CHILD | WS_VISIBLE, /* Estilo */
      9, 49,           /* Posición */
      95, 24,          /* Tamaño */
      hwnd,            /* Ventana padre */
      (HMENU)ID_STATIC,/* Identificador del control */
      hInstance,       /* Instancia */
      NULL);           /* Sin datos de creación de ventana */

Cuando existen controles con el estilo owner-draw, la ventana padre del control recibirá un mensaje WM_DRAWITEM cada vez que el control deba ser redibujado. Este mensaje se recibe para todos los controles owner-draw existentes, de modo que deberemos distinguir a qué control en concreto se refiere el mensaje. Esta es la parte sencilla, ya que en el parámetro wParam de este mensaje recibiremos el identificador del control.

Por otra parte, en el parámetro lParam, recibiremos un puntero a una estructura DRAWITEMSTRUCT, que nos proporciona información sobre todos los detalles necesarios para decidir el modo en que debemos dibujar el control.

Por una parte, el campo CtlType contendrá el valor ODT_STATIC, indicando que el control es un control estático. El campo CtlID contiene el identificador del control. El campo itemID no tiene ninguna información en el caso de un control estático. El campo itemAction contiene un valor que especifica el tipo de acción de dibujo requerido. Sólo puede ser ODA_DRAWENTIRE, si se necesita actualizar el control completo, ya que estos controles no pueden tener el foco ni ser seleccionados.

El campo itemState especifica el estado del control. En el caso de los controles estáticos, el valor de este campo sólo puede ser: ODS_DISABLED, si el control está deshabilitado.

El campo hwndItem contiene el manipulador de ventana, hDC contiene el manipulador de contexto de dispositivo del control. El campo rcItem contiene el rectángulo que define los límites de la zona a dibujar. E itemData no contiene nada válido en el caso de los controles estáticos.

Este ejemplo visualiza un control estático con forma elíptica:

   LPDRAWITEMSTRUCT lpdis;
        case WM_DRAWITEM:
           lpdis = (LPDRAWITEMSTRUCT)lParam;
           SendDlgItemMessage(hwnd, (UINT)wParam, WM_GETTEXT, 128, (LPARAM)cad);
           GetClientRect(lpdis->hwndItem, &re);
           SetBkMode(lpdis->hDC, TRANSPARENT);
           FillRect(lpdis->hDC, &re, (HBRUSH)GetStockObject(LTGRAY_BRUSH));
           SelectObject(lpdis->hDC, (HBRUSH)GetStockObject(GRAY_BRUSH));
           SelectObject(lpdis->hDC, (HPEN)GetStockObject(WHITE_PEN));
           Ellipse(lpdis->hDC, re.left, re.top, re.right, re.bottom);
           TextOut(lpdis->hDC, re.left+12, re.top+2, cad, strlen(cad));
           return 0;

Ejemplo 70


  Nombre Fichero Fecha Tamaño Contador Descarga
D Ejemplo 70 win070.zip 2007-03-15 6554 bytes 175