Respuesta al teclado

Los controles de barra de desplazamiento tienen un interfaz de teclado predefinido, de modo que cuando tienen el foco, ciertas pulsaciones de teclas se convierten en mensajes WM_HSCROLL o WM_VSCROLL.

En la siguiente tabla vemos las teclas que se procesan, y qué códigos de notificación generan:

Tecla Código de notificación
Vertical Horizontal
Flecha arriba SB_LINEUP SB_LINELEFT
Flecha abajo SB_LINEDOWN SB_LINERIGHT
Flecha derecha SB_LINEDOWN SB_LINERIGHT
Flecha izquierda SB_LINEUP SB_LINELEFT
Página abajo SB_PAGEDOWN SB_PAGERIGHT
Página arriba SB_PAGEUP SB_PAGELEFT
Fin SB_BOTTOM
Inicio SB_TOP

Vemos que en esta tabla aparecen dos códigos de notificación que no se comentaron en el punto anterior: SB_TOP y SB_BOTTOM. Esto se debe a que estos dos códigos sólo pueden ser generados mediante el teclado.

En un control de barra de desplazamiento vertical, SB_TOP indica que el cursor se debe desplazar al tope superior, y SB_BOTTOM al inferior. En controles horizontales indica los extremos izquierdo y derecho del control, respectivamente.

Las barras de desplazamiento estándar no tienen este interfaz de teclado definido, pero se puede hacer algo análogo procesando mensajes WM_KEYDOWN y enviando correspondientes mensajes WM_HSCROLL y WM_VSCROLL a la ventana.

Ejemplo 75


  Nombre Fichero Fecha Tamaño Contador Descarga
D Ejemplo 75 win075.zip 2007-03-15 3825 bytes 164

Desplazar contenido de ventanas

El uso más común de las barras de desplazamiento estándar es permitir la posibilidad de mostrar distintas áreas de un documento cuando éste no puede ser mostrado íntegramente en el área de cliente.

Cuando se responde a códigos de notificación como SB_PAGEUP, SB_PAGEDOWN, SB_TOP, etc, generalmente será necesario generar el contenido completo del área de cliente. Sin embargo, ante códigos como SB_LINEUP o SB_LINERIGHT, sólo una pequeña parte del área de cliente queda invalidada, el resto sigue siendo válida, después de desplazarla algunos pixels en la dirección adecuada.

Estas operaciones de desplazamientos de mapas de bits son tan frecuentes que, inevitablemente, el API dispone de funciones para realizarlas. Se trata de las funciones ScrollWindow y ScrollWindowEx, de las que es recomendable usar la segunda, ya que la primera se mantiene sólo por compatibilidad con versiones anteriores del API.

Esta función tiene bastantes parámetros, pero veremos que algunos de ellos no tendrán mucho uso en la mayor parte de los casos.

El primer parámetro es el manipulador de la ventana cuya área de cliete queremos desplazar.

El segundo indica las únidades lógicas a desplazar horizontalmente. Los valores negativos indican desplazamientos a la izquierda.

El tercer parámetro indica las unidades lógicas a desplazar verticalmente. Los valores negativos son desplazamientos hacia arriba.

El cuarto parámetros es un puntero a una estructrua RECT que indica la zona rectangular, dentro del área de cliete, que queremos desplazar. Si usamos el valor NULL se tomará el rectángulo correspondienta al área de cliente completa.

El quinto parámetro también es un puntero a una estructura RECT que define un área rectangular de recorte. Sólo los puntos dentro de ese área se verán afectados, de modo que los puntos fuera de ella que después del desplazamiento estén dentro se pintarán, pero los que estén dentro que posteriormente queden fuera, no. De nuevo, si se especifica el valor NULL, el rectángulo de recorte coincidirá con el del parámetro anterior.

El sexto parámetro es un manipulador de región. Antes de la llamada, esa región puede contener la zona de actualización actual, y la función la modificará para incluir las nuevas zonas que deben ser actualizadas. Si no nos interesa usar esta región, de nuevo podemos usar el valor NULL.

El séptimo parámetro es un puntero a una estructura RECT, la función actualiza ese rectángulo con la región rectangular invalidada después de realizado el desplazamiento. También podemos ignorar este dato usando el valor NULL.

El octavo y último parámetro es una bandera que puede tomar tres valores diferentes:

  • SW_INVALIDATE: invalida la región identificada por el sexto parámetro una vez realizado el desplazamiento.
  • SW_ERASE: Borra la región invalidada enviando un mensaje WM_ERASEBKGND a la ventana, cuando se especifica junto a valor SW_INVALIDATE.
  • SW_SCROLLCHILDREN: desplaza también las ventanas hijas incluidas en el área a desplazar. Además, se envía un mensaje WM_MOVE a cada una de las ventanas interseccionadas por ese área, aunque no hayan sido movidas.
   ScrollWindowEx(hwnd, 10, 0, &re, NULL, NULL, NULL, SW_INVALIDATE);

El uso de esta función implica, generalmente, procesar el mensaje WM_PAINT.

Otra función útil para desplazar el contenido de una ventana es ScrollDC. Esta función es muy parecida a la anterior, pero en lugar de un manipulador de ventana, se usa un manipulador de contexto de dispositivo, y no dispone del parámetro de banderas.

Existen además dos funciones que pueden resultar útiles para usar conjuntamente, como son UpdateWindow y RedrawWindow. La primera sirve para actualizar el área de cliente. Para ello se envía un mensaje WM_PAINT, si la región de actualización no es nula, evitando la cola, con lo que se procesará inmediatamente, el envío del mensaje se omite si esta región está vacía.

La segunda función es algo más complicada, pero tiene un funcionamiento parecido. También sirve para actualizar una zona de la ventana, pero al contrario que la anterior, podemos especificar un rectángulo o una región de actualización.

El primer parámetro es un manipulador de la ventana que queremos actualizar.

El segundo es un puntero a una estructura RECT que contiene el rectángulo de actualización.

El tercero es un manipulador de una región de actualización, si se especifica una regino en este parámetro, se ignora cualquier valor del anterior. Si ambos son NULL, se actualiza toda el área de cliente.

El último parámetro son banderas que pueden afectar al modo en que trabaja la función, validando o invalidando la región especificada, indicando si debe actualizar o borra el contenido, u opciones sobre las ventanas hijas. Ver la descripción de la función RedrawWindow para más detalles.

  RedrawWindow(hwnd, NULL, NULL, RDW_UPDATENOW | RDW_ALLCHILDREN);

Colores y medidas

Generalmente, usaremos los colores y medidas estándar para las barras de desplazamiento. Ya hemos visto que el único color que podemos personalizar es el del fondo de la zona de desplazamiento en la barra, el resto corresponde con los colores normales de los botones, ya que las flechas y el cursor se comportan, en cieto modo, como tales.

En cuanto a los colores, ya sabemos que podemos usar las funciones GetSysColor y SetSysColors para obtener o modificar, respectivamente, los valores de color del sistema. Concretamente, para este caso, nos interesa el valor de COLOR_SCROLLBAR, que es el color del fondo de la zona de desplazamiento.

Valores de medidas del sistema

Las barras de desplazamiento estándar horizontales tienen definidas unas medidas en el sistema: SM_CXHSCROLL para la anchura y SM_CYHSCROLL para la altura. Del mismo modo, las verticales tienen unas medidas SM_CXVSCROLL para la anchura y SM_CYVSCROLL para la altura.

Para obtener estos valores se puede usar la función GetSystemMetrics, indicando la constante que interese.

   int anchura;
 
   anchura = GetSystemMetrics(SM_CXHSCROLL);

Los valores que podemos obtener mediante GetSystemMetrics son los siguientes:

Constante Descripción
SM_CXHSCROLL Anchura del mapa de bits de la flela en una barra de desplazamiento horizontal.
SM_CXHTHUMB Anchura de la caja de desplazamiento en una barra horizontal. A partir de la versión 4.0, este valor recupara la anchura de una barra de desplazamiento cuyo tamaño de página es cero.
SM_CXVSCROLL Anchura del mapa de bits de la flecha en una barra de desplazamiento vertical.
SM_CYHSCROLL Altura del mapa de bits de la flecha en una barra de desplazamiento horizontal.
SM_CYVSCROLL Altura del mapa de bits de la flecha en una barra de desplazamiento vertical.
SM_CYVTHUMB Altura de la caja de desplazamiento en una barra vertical. A partir de la versión 4.0, este valor recupera la altura de una barra de desplazamiento cuyo tamaño de página es cero.

Otros mensajes

Además de todos los mensajes comentados en el capítulo 12 y en este, hasta ahora, existen dos de los que no hemos hablado.

El primero de ellos es SBM_GETRANGE, que nos sirve para recuperar los valores mínimo y máximo del rango de un control de barra de desplazamiento.

En el parámetro wParam enviaremos un puntero a un entero, en ese entero recibiremos el valor mínimo del rango. En el parámetro lParam enviaremos otro puntero a un entero, en este recibiremos el valor máximo del rango.

El segundo mensaje es SBM_SETRANGEREDRAW, que se comporta de forma idéntica a SBM_SETRANGE, salvo que además de asignar un rango al control de barra de desplazamiento, también redibuja el control para mostrar su nuevo estado.

Como en el caso de SBM_SETRANGE, en el parámetro wParam pasaremos el valor mínimo del rango, y en lParam, el máximo.

Ejemplo 76


  Nombre Fichero Fecha Tamaño Contador Descarga
D Ejemplo 76 win076.zip 2007-03-15 258975 bytes 296