Capítulo 36 Aceleradores

Los aceleradores son atajos para los menús. Lo normal y deseable es que nuestras aplicaciones proporcionen aceleradores para las opciones más frecuentes de los menús.

Un acelerador es una pulsación de tecla, o de teclas, que producen el mismo efecto que una selección en un menú. Windows detecta la pulsación y convierte el menaje de teclado a un mensaje WM_COMMAND o WM_SYSCOMMAND.

Cuando el usuario se familiariza con los aceleradores de teclado puede ahorrar mucho tiempo al activar comandos, ya que es mucho más rápido pulsar una tecla que activar una opción de menú, ya sea mediante el teclado o el ratón.

Recursos de aceleradores

Como ya hemos visto con los menús, cuadros de diálogo, cadenas, etc, en el caso de los aceleradores también podemos crearlos como un recurso, y cargarlos por la aplicación cuando se necesiten.

Fichero de recursos

Para crear una tabla de aceleradores se usa la sentencia ACCELERATORS:

aceleradores ACCELERATORS
BEGIN
  VK_F1, CM_OPCION1, VIRTKEY  /* F1 */
  "^C",  CM_SALIR             /* Control C */
  "K",   CM_OPCION2           /* K */
  "k",   CM_OPCION3, ALT      /* Alt k */
  0x34,  CM_OPCION4, ASCII    /* 4 */
  VK_F2, CM_OPCION5, ALT, SHIFT, VIRTKEY    /* Alt Mays F2 */
  "1",   CM_OPCION6, ALT, CONTROL, VIRTKEY  /* Alt Control 1 */
END

Si queremos que nuestros aceleradores no distingan mayúsculas de minúsculas, es mucho mejor definirlos a partir de teclas virtuales.

Cargar aceleradores desde recursos

Para cargar los aceleradores desde un recurso se usa la función LoadAccelerators. Como ya viene siendo corriente con este grupo de funciones, esta también necesita dos parámetros. El primero es un manipulador de la instancia del módulo que contiene el recurso, el segundo, es el identificador de recurso.

HACCEL hAcelerador = LoadAccelerators(hThisInstance, "aceleradores");

Bucle de mensajes para usar aceleradores

Para que nuestra aplicación reciba mensajes cuando se pulsan las teclas que definen los aceleradores hay que modificar el bucle de mensajes. Los mensajes WM_KEYDOWN y WM_SYSKEYDOWN deben traducirse a mensajes WM_COMMAND y WM_SYSCOMMAND, y para ello hay que usar la función TranslateAccelerator:

    while(TRUE == GetMessage(&mensaje, NULL, 0, 0))
    {
        /* Traducir mensajes de teclas a mensajes de acelerador */
        if(!TranslateAccelerator(hwnd, hAcelerador, &mensaje)) {
           /* Traducir mensajes de teclas virtuales a mensajes de caracteres 
              sólo si TranslateAccelerator regresa con nulo */
           TranslateMessage(&mensaje);
           /* Enviar mensaje al procedimiento de ventana */
           DispatchMessage(&mensaje);
        }
    }

Crear tablas de aceleradores sin usar recursos

Se usa la función CreateAcceleratorTable para crear tablas de aceleradores durante la ejecución, a partir de un array de estructuras ACCEL. El manipulador de aceleradores obtenido mediante esta función se puede usar igual que el obtenido por la función LoadAccelerators.

Un detalle importante: las tablas de aceleradores creadas mediante CreateAcceleratorTable se deben destruir antes de terminar la aplicación mediante una llamad a la función DestroyAcceleratorTable. Esto no es necesario cuando se usa la función LoadAccelerators.

En general usaremos aceleradores de recursos, ya que son más fáciles de manejar. Sin embargo, este procedimiento nos permitiría, por ejemplo, crear aceleradores definidos por el usuario.

Combinar aceleradores y menús

En general, los aceleradores estarán ligados a opciones de menú, pero no hay nada que informe al usuario sobre los aceleradores disponibles, salvo que nosotros lo indiquemos directamente.

Una forma fácil de hacerlo es añadir la información del acelerador al ítem del menú. Seguro que has notado que algunas opciones de menú tienen una combinación de teclas a su derecha, por ejemplo, en el menú de sistema de cualquier ventana la última opción es la de "Cerrar", y a su derecha aparece el texto "Alt+F4". Eso es un acelerador.

Nosotros podemos hacer lo mismo con nuestros menús. Es muy fácil añadir información a la derecha del texto de un ítem, basta con insertar la secuencia "\a", y a continuación el texto del acelerador. El texto después de la secuencia "\a" se justifica a la derecha:

menu MENU
BEGIN
 POPUP "&Principal"
 BEGIN
  MENUITEM "Opción &1\aF1", CM_OPCION1
  MENUITEM "Opción &2\aK", CM_OPCION2
  MENUITEM "Opción &3\aAlt+k", CM_OPCION3
  MENUITEM "Opción &4\a4", CM_OPCION4
  MENUITEM "Opción &5\aAlt+Mays+F2", CM_OPCION5
  MENUITEM "Opción &6\aAlt+Ctrl+1", CM_OPCION6
  MENUITEM SEPARATOR
  MENUITEM "&Salir\a^C", CM_SALIR
 END
END

Aceleradores globales

Existen varios aceleradores definidos a nivel global de Windows, nuestras aplicaciones deben intentar evitar definir esos aceleradores, aunque en principio no es imposible hacerlo, sencillamente no es aconsejable. Los aceleradores son:

Acelerador Descripción
ALT+ESC Cambia a la siguiente aplicación.
ALT+F4 Cierra una aplicación o ventana.
ALT+HYPHEN Abre el menú de sistema de una ventana de documento.
ALT+PRINT SCREEN Copia una imagen de la ventana activa al portapapeles.
ALT+SPACEBAR Abre el menú de sistema para una ventana de aplicación.
ALT+TAB Cambia a la siguiente aplicación.
CTRL+ESC Cambia a la lista de tareas de Windows (menú de Inicio).
CTRL+F4 Cierra el grupo activo o ventana de documento.
F1 Arranca la ayuda si la aplicación la tiene.
PRINT SCREEN Copia una imagen de la pantalla al portapapeles.
SHIFT+ALT+TAB Cambia a la aplicación anterior. El usuario debe presionar Alt+Mays mientras presiona TAB.

Diferencia entre acelerador y menú

Usar un acelerador es prácticamente lo mismo que activar un ítem de un menú. En ambos casos se envía un mensaje WM_COMMAND o WM_SYSCOMMAND, y nuestro procedimiento de ventana lo procesará del mismo modo. En un caso el identificador será el que hemos usado para el acelerador, y en el otro el que hemos usado para el ítem del menú.

Sin embargo es posible que a veces nos interese saber si un comando procede de un acelerador o de un menú. Para saberlo podemos comprobar la presencia de un bit, el código de notificación del mensaje WM_COMMAND, que se proporciona en la palabra de mayor peso del parámetro wParam.

Ejemplo 41


  Nombre Fichero Fecha Tamaño Contador Descarga
D Ejemplo 41 win041.zip 2004-07-16 3680 bytes 238