Introducción a la entrada de teclado

Las aplicaciones deben aceptar entradas de usuario desde el teclado, así como desde el mouse. Una aplicación recibe entradas de teclado en forma de mensajes publicados en sus ventanas.

Modelo de entrada de teclado

El sistema proporciona compatibilidad con teclados independientes del dispositivo para las aplicaciones mediante la instalación de un controlador de dispositivo de teclado adecuado para el teclado actual. El sistema proporciona compatibilidad con teclados independientes del idioma utilizando el diseño de teclado específico del idioma que selecciona actualmente el usuario o la aplicación. El controlador de dispositivo de teclado recibe códigos de tecla del teclado, que se envían al diseño del teclado, donde se traducen en mensajes y se publican en las ventanas adecuadas de la aplicación.

A cada tecla de un teclado se le asigna un valor único denominado código de tecla, un identificador dependiente del dispositivo para la tecla del teclado. Un teclado genera dos códigos de tecla cuando el usuario pulsa una tecla: uno cuando el usuario presiona la tecla y otro cuando el usuario suelta la tecla.

El controlador de dispositivo de teclado interpreta un código de tecla y lo traduce (asigna) a un código de tecla virtual, un valor independiente del dispositivo definido por el sistema que identifica el propósito de una tecla. Una vez traducido un código de tecla, el diseño del teclado crea un mensaje que incluye el código de tecla, el código de tecla virtual y otra información sobre la pulsación de tecla y, después, coloca el mensaje en la cola de mensajes del sistema. El sistema quita el mensaje de la cola de mensajes del sistema y lo envía a la cola de mensajes del subproceso adecuado. Finalmente, el bucle de mensajes del subproceso quita el mensaje y lo pasa al procedimiento de ventana adecuado para su procesamiento. En la ilustración siguiente se muestra el modelo de entrada de teclado.

keyboard input processing model

Foco y activación del teclado

El sistema envía mensajes de teclado a la cola de mensajes del subproceso en primer plano que creó la ventana con el foco del teclado. El foco del teclado es una propiedad temporal de una ventana. El sistema comparte el teclado entre todas las ventanas de la pantalla cambiando el foco del teclado, según lo indique el usuario, de una ventana a otra. La ventana que tiene el foco del teclado recibe (de la cola de mensajes del subproceso que la creó) todos los mensajes de teclado hasta que el foco cambia a otra ventana.

Un subproceso puede llamar a la función GetFocus para determinar cuál de sus ventanas (si procede) tiene actualmente el foco del teclado. Un subproceso puede dar el foco del teclado a una de sus ventanas llamando a la función SetFocus. Cuando el foco del teclado cambia de una ventana a otra, el sistema envía un mensaje WM_KILLFOCUS a la ventana que ha perdido el foco y, después, envía un mensaje WM_SETFOCUS a la ventana que ha obtenido el foco.

El concepto de foco del teclado está relacionado con el de ventana activa. La ventana activa es la ventana de nivel superior con la que el usuario está trabajando actualmente. La ventana con el foco del teclado es la ventana activa o una ventana secundaria de la ventana activa. Para ayudar al usuario a identificar la ventana activa, el sistema la coloca en la parte superior del orden Z y resalta su barra de título (si tiene una) y el borde.

El usuario puede activar una ventana de nivel superior haciendo clic en ella, seleccionándola con la combinación de teclas ALT+TAB o ALT+ESC o seleccionándola en la lista de tareas. Un subproceso puede activar una ventana de nivel superior mediante la función SetActiveWindow. Puede determinar si una ventana de nivel superior que creó está activa mediante la función GetActiveWindow.

Cuando se desactiva una ventana y se activa otra, el sistema envía el mensaje WM_ACTIVATE. La palabra de valor inferior del parámetro wParam es cero si la ventana se está desactivando y distinta de cero si se está activando. Cuando el procedimiento de ventana predeterminado recibe el mensaje WM_ACTIVATE, establece el foco del teclado en la ventana activa.

Para impedir que los eventos de entrada de teclado y mouse lleguen a las aplicaciones, use BlockInput. Tenga en cuenta que la función BlockInput no interferirá con la tabla asincrónica de estado de entrada del teclado. Esto significa que llamar a la función SendInput mientras la entrada está bloqueada cambiará la tabla asincrónica de estado de entrada del teclado.

Mensajes de pulsación de tecla

Al presionar una tecla, se coloca un mensaje WM_KEYDOWN o WM_SYSKEYDOWN en la cola de mensajes del subproceso asociada a la ventana que tiene el foco del teclado. Soltar una tecla hace que se coloque un mensaje WM_KEYUP o WM_SYSKEYUP en la cola.

Los mensajes de tecla arriba y abajo suelen aparecer en pares, pero si el usuario mantiene presionada una tecla el tiempo suficiente como para iniciar la característica de repetición automática del teclado, el sistema genera una serie de mensajes WM_KEYDOWN o WM_SYSKEYDOWN seguidos. Después, genera un único mensaje WM_KEYUP o WM_SYSKEYUP cuando el usuario suelta la tecla.

En esta sección se describen los temas siguientes:

Pulsaciones de tecla del sistema y que no son del sistema

El sistema distingue entre pulsaciones de tecla del sistema y pulsaciones de tecla que no son del sistema. Las pulsaciones de tecla del sistema producen mensajes de pulsación de tecla del sistema, WM_SYSKEYDOWN y WM_SYSKEYUP. Las pulsaciones de tecla que no son del sistema producen mensajes de pulsación de tecla que no son del sistema, WM_KEYDOWN y WM_KEYUP.

Si el procedimiento de ventana debe procesar un mensaje de pulsación de tecla del sistema, asegúrese de que, después de procesar el mensaje, el procedimiento lo pasa a la función DefWindowProc. De lo contrario, todas las operaciones del sistema que impliquen la tecla ALT se deshabilitarán siempre que la ventana tenga el foco del teclado. Es decir, el usuario no podrá acceder a los menús de la ventana o al menú Sistema, ni podrá usar la combinación de teclas ALT+ESC o ALT+TAB para activar una ventana diferente.

Los mensajes de pulsación de tecla del sistema son principalmente para que los utilice el sistema en lugar de una aplicación. El sistema los usa para proporcionar su interfaz de teclado integrada a los menús y permitir que el usuario controle qué ventana está activa. Los mensajes de pulsación de tecla del sistema se generan cuando el usuario pulsa una tecla en combinación con la tecla ALT, o cuando el usuario escribe y no hay ninguna ventana con el foco del teclado (por ejemplo, cuando se minimiza la aplicación activa). En este caso, los mensajes se envían a la cola de mensajes asociada a la ventana activa.

Los mensajes de pulsación de tecla que no son del sistema son para que los usen las ventanas de la aplicación; la función DefWindowProc no hace nada con ellos. Un procedimiento de ventana puede descartar los mensajes de pulsación de tecla que no son del sistema que no necesite.

Códigos de tecla virtual descritos

El parámetro wParam de un mensaje de pulsación de tecla contiene el código de tecla virtual de la tecla que se presionó o se soltó. Un procedimiento de ventana procesa u omite un mensaje de pulsación de tecla en función del valor del código de tecla virtual.

Un procedimiento de ventana típico procesa solo un pequeño subconjunto de los mensajes de pulsación de tecla que recibe y omite el resto. Por ejemplo, un procedimiento de ventana solo puede procesar mensajes de pulsación de tecla WM_KEYDOWN y solo aquellos que contengan códigos de tecla virtual para las teclas de movimiento del cursor, las teclas de mayúsculas (también denominadas teclas de control) y las teclas de función. Un procedimiento de ventana típico no procesa los mensajes de pulsación de tecla de las teclas de caracteres. En su lugar, usa la función TranslateMessage para convertir el mensaje en mensajes de caracteres. Para obtener más información sobre TranslateMessage y los mensajes de caracteres, vea Mensajes de caracteres.

Marcas de mensaje de pulsación de tecla

El parámetro lParam de un mensaje de pulsación de tecla contiene información adicional sobre la pulsación de tecla que generó el mensaje. Esta información incluye el recuento de repeticiones, el código de tecla, la marca de tecla extendida, el código de contexto, la marca de estado de tecla anterior y la marca de estado de transición. En la ilustración siguiente se muestran las ubicaciones de estas marcas y los valores en el parámetro lParam.

the locations of the flags and values in the lparam parameter of a keystroke message

Una aplicación puede usar los siguientes valores para obtener las marcas de pulsación de tecla de la palabra de valor superior de lParam.

Valor Descripción
KF_EXTENDED
0x0100
Manipula la marca de tecla extendida.
KF_DLGMODE
0x0800
Manipula la marca del modo de diálogo, que indica si hay un cuadro de diálogo activo.
KF_MENUMODE
0x1000
Manipula la marca del modo de menú, que indica si hay un menú activo.
KF_ALTDOWN
0x2000
Manipula la marca de código de contexto.
KF_REPEAT
0x4000
Manipula la marca de estado de tecla anterior.
KF_UP
0x8000
Manipula la marca de estado de transición.

Código de ejemplo:

case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
{
    WORD vkCode = LOWORD(wParam);                                 // virtual-key code
    
    WORD keyFlags = HIWORD(lParam);

    WORD scanCode = LOBYTE(keyFlags);                             // scan code
    BOOL isExtendedKey = (keyFlags & KF_EXTENDED) == KF_EXTENDED; // extended-key flag, 1 if scancode has 0xE0 prefix
    
    if (isExtendedKey)
        scanCode = MAKEWORD(scanCode, 0xE0);

    BOOL wasKeyDown = (keyFlags & KF_REPEAT) == KF_REPEAT;        // previous key-state flag, 1 on autorepeat
    WORD repeatCount = LOWORD(lParam);                            // repeat count, > 0 if several keydown messages was combined into one message

    BOOL isKeyReleased = (keyFlags & KF_UP) == KF_UP;             // transition-state flag, 1 on keyup

    // if we want to distinguish these keys:
    switch (vkCode)
    {
    case VK_SHIFT:   // converts to VK_LSHIFT or VK_RSHIFT
    case VK_CONTROL: // converts to VK_LCONTROL or VK_RCONTROL
    case VK_MENU:    // converts to VK_LMENU or VK_RMENU
        vkCode = LOWORD(MapVirtualKeyW(scanCode, MAPVK_VSC_TO_VK_EX));
        break;
    }

    // ...
}
break;

Número de repeticiones

Puede comprobar el recuento de repeticiones para determinar si un mensaje de pulsación de tecla representa más de una pulsación de tecla. El sistema incrementa el recuento cuando el teclado genera mensajes WM_KEYDOWN o WM_SYSKEYDOWN más rápido de lo que una aplicación puede procesarlos. Esto suele ocurrir cuando el usuario mantiene presionada una tecla el tiempo suficiente como para iniciar la característica de repetición automática del teclado. En lugar de rellenar la cola de mensajes del sistema con los mensajes de tecla hacia abajo resultantes, el sistema combina los mensajes en un solo mensaje de tecla hacia abajo e incrementa el recuento de repeticiones. Soltar una tecla no puede iniciar la característica de repetición automática, por lo que el recuento de repeticiones para los mensajes WM_KEYUP y WM_SYSKEYUP siempre se establece en 1.

Códigos de tecla

Diagram of a Type 4 keyboard with the key locations for each key.

El código de tecla es el valor que genera el sistema cuando el usuario presiona una tecla. Es un valor que identifica la tecla presionada independientemente de la distribución de teclado activa, en lugar del carácter representado por la tecla. Normalmente, una aplicación omite los códigos de tecla. En su lugar, usa los códigos de tecla virtual para interpretar los mensajes de pulsación de tecla.

Los teclados modernos usan la especificación de Dispositivos de interfaz humana (HID) para comunicarse con un equipo. El controlador del teclado convierte los valores de uso de HID enviados desde el teclado en códigos de tecla y los pasa a las aplicaciones.

Nota:

Aunque los códigos de tecla virtual suelen ser más útiles para las aplicaciones de escritorio, puede que se requieran códigos de tecla en casos específicos, cuando necesite saber qué tecla se presiona independientemente del diseño de teclado de ese momento. Por ejemplo, los enlaces de teclado WASD (W es arriba, A es izquierda, S es abajo y D es derecha) para juegos, que garantizan una formación de teclas coherente entre los diseños de teclado QWERTY EE. UU. o AZERTY francés.

En la tabla siguiente se muestra el conjunto de códigos de tecla que Windows reconoce actualmente. Los valores de Página de uso de HID/Id. de uso de HID/Nombre de uso de HID hacen referencia al documento de tablas de uso de HID. Los valores de ubicación de la tecla hacen referencia a la imagen del teclado anterior.

El código de Tecla 1 Make se ofrece en WM_KEYDOWN/WM_KEYUP/WM_SYSKEYDOWN/WM_SYSKEYUP y WM_INPUT messages.

Nombre de página de uso de HID Nombre de uso de HID Página de uso de HID Id. de uso de HID Tecla 1 Make Ubicación de la tecla
Escritorio genérico Apagado del sistema 0x0001 0x0081 0xE05E
Escritorio genérico Suspensión del sistema 0x0001 0x0082 0xE05F
Escritorio genérico Reactivación del sistema 0x0001 0x0083 0xE063
Teclado/Teclado numérico ErrorRollOver 0x0007 0x0001 0x00FF
Teclado/Teclado numérico Teclado A 0x0007 0x0004 0x001E 31
Teclado/Teclado numérico Teclado B 0x0007 0x0005 0x0030 50
Teclado/Teclado numérico Teclado C 0x0007 0x0006 0x002E 48
Teclado/Teclado numérico Teclado D 0x0007 0x0007 0x0020 33
Teclado/Teclado numérico Teclado E 0x0007 0x0008 0x0012 19
Teclado/Teclado numérico Teclado F 0x0007 0x0009 0x0021 34
Teclado/Teclado numérico Teclado G 0x0007 0x000A 0x0022 35
Teclado/Teclado numérico Teclado H 0x0007 0x000B 0x0023 36
Teclado/Teclado numérico Teclado I 0x0007 0x000C 0x0017 24
Teclado/Teclado numérico Teclado J 0x0007 0x000D 0x0024 37
Teclado/Teclado numérico Teclado K 0x0007 0x000E 0x0025 38
Teclado/Teclado numérico Teclado L 0x0007 0x000F 0x0026 39
Teclado/Teclado numérico Teclado M 0x0007 0x0010 0x0032 52
Teclado/Teclado numérico Teclado N 0x0007 0x0011 0x0031 51
Teclado/Teclado numérico Teclado O 0x0007 0x0012 0x0018 25
Teclado/Teclado numérico Teclado P 0x0007 0x0013 0x0019 26
Teclado/Teclado numérico Teclado Q 0x0007 0x0014 0x0010 17
Teclado/Teclado numérico Teclado R 0x0007 0x0015 0x0013 20
Teclado/Teclado numérico Teclado S 0x0007 0x0016 0x001F 32
Teclado/Teclado numérico Teclado T 0x0007 0x0017 0x0014 21
Teclado/Teclado numérico Teclado U 0x0007 0x0018 0x0016 23
Teclado/Teclado numérico Teclado V 0x0007 0x0019 0x002F 49
Teclado/Teclado numérico Teclado W 0x0007 0x001A 0x0011 18
Teclado/Teclado numérico Teclado X 0x0007 0x001B 0x002D 47
Teclado/Teclado numérico Teclado Y 0x0007 0x001C 0x0015 22
Teclado/Teclado numérico Teclado Z 0x0007 0x001D 0x002C 46
Teclado/Teclado numérico Teclado 1 y exclamación de cierre 0x0007 0x001E 0x0002 2
Teclado/Teclado numérico Teclado 2 y arroba 0x0007 0x001F 0x0003 3
Teclado/Teclado numérico Teclado 3 y almohadilla 0x0007 0x0020 0x0004 4
Teclado/Teclado numérico Teclado 4 y dólar 0x0007 0x0021 0x0005 5
Teclado/Teclado numérico Teclado 5 y porcentaje 0x0007 0x0022 0x0006 6
Teclado/Teclado numérico Teclado 6 y símbolo de intercalación 0x0007 0x0023 0x0007 7
Teclado/Teclado numérico Teclado 7 e Y comercial 0x0007 0x0024 0x0008 8
Teclado/Teclado numérico Teclado 8 y estrella 0x0007 0x0025 0x0009 9
Teclado/Teclado numérico Teclado 9 y paréntesis izquierdo 0x0007 0x0026 0x000A 10
Teclado/Teclado numérico Teclado 0 y paréntesis derecho 0x0007 0x0027 0x000B 11
Teclado/Teclado numérico Teclado Retorno 0x0007 0x0028 0x001C 43
Teclado/Teclado numérico Teclado Escape 0x0007 0x0029 0x0001 110
Teclado/Teclado numérico Teclado Eliminar 0x0007 0x002A 0x000E 15
Teclado/Teclado numérico Teclado Tabulación 0x0007 0x002B 0x000F 16
Teclado/Teclado numérico Teclado Barra espaciadora 0x0007 0x002C 0x0039 61
Teclado/Teclado numérico Teclado Guion y Subrayado 0x0007 0x002D 0x000C 12
Teclado/Teclado numérico Teclado Igual y Más 0x0007 0x002E 0x000D 13
Teclado/Teclado numérico Teclado Llave izquierda 0x0007 0x002F 0x001A 27
Teclado/Teclado numérico Teclado Llave derecha 0x0007 0x0030 0x001B 28
Teclado/Teclado numérico Teclado Barra vertical y diagonal 0x0007 0x0031 0x002B 29
Teclado/Teclado numérico Teclado No EE. UU. 0x0007 0x0032 0x002B 42
Teclado/Teclado numérico Teclado Punto y coma y Dos puntos 0x0007 0x0033 0x0027 40
Teclado/Teclado numérico Teclado Apóstrofo y Comillas dobles 0x0007 0x0034 0x0028 41
Teclado/Teclado numérico Teclado Acento grave y Tilde 0x0007 0x0035 0x0029 1
Teclado/Teclado numérico Teclado Coma 0x0007 0x0036 0x0033 53
Teclado/Teclado numérico Teclado Punto 0x0007 0x0037 0x0034 54
Teclado/Teclado numérico Teclado Signo de interrogación 0x0007 0x0038 0x0035 55
Teclado/Teclado numérico Teclado Bloqueo de mayúsculas 0x0007 0x0039 0x003A 30
Teclado/Teclado numérico Teclado F1 0x0007 0x003A 0x003B 112
Teclado/Teclado numérico Teclado F2 0x0007 0x003B 0x003C 113
Teclado/Teclado numérico Teclado F3 0x0007 0x003C 0x003D 114
Teclado/Teclado numérico Teclado F4 0x0007 0x003D 0x003E 115
Teclado/Teclado numérico Teclado F5 0x0007 0x003E 0x003F 116
Teclado/Teclado numérico Teclado F6 0x0007 0x003F 0x0040 117
Teclado/Teclado numérico Teclado F7 0x0007 0x0040 0x0041 118
Teclado/Teclado numérico Teclado F8 0x0007 0x0041 0x0042 119
Teclado/Teclado numérico Teclado F9 0x0007 0x0042 0x0043 120
Teclado/Teclado numérico Teclado F10 0x0007 0x0043 0x0044 121
Teclado/Teclado numérico Teclado F11 0x0007 0x0044 0x0057 122
Teclado/Teclado numérico Teclado F12 0x0007 0x0045 0x0058 123
Teclado/Teclado numérico Teclado Impresión de pantalla 0x0007 0x0046 0xE037
0x0054 *Nota 1
124
Teclado/Teclado numérico Teclado Bloq despl 0x0007 0x0047 0x0046 125
Teclado/Teclado numérico Teclado Pausa 0x0007 0x0048 0xE11D45
0xE046 *Nota 2
0x0045 *Nota 3
126
Teclado/Teclado numérico Teclado Insertar 0x0007 0x0049 0xE052 75
Teclado/Teclado numérico Teclado Inicio 0x0007 0x004A 0xE047 80
Teclado/Teclado numérico Teclado RePág 0x0007 0x004B 0xE049 85
Teclado/Teclado numérico Teclado Eliminar hacia delante 0x0007 0x004C 0xE053 76
Teclado/Teclado numérico Teclado Fin 0x0007 0x004D 0xE04F 81
Teclado/Teclado numérico Teclado AvPág 0x0007 0x004E 0xE051 86
Teclado/Teclado numérico Teclado Flecha derecha 0x0007 0x004F 0xE04D 89
Teclado/Teclado numérico Teclado Flecha Izquierda 0x0007 0x0050 0xE04B 79
Teclado/Teclado numérico Teclado Flecha abajo 0x0007 0x0051 0xE050 84
Teclado/Teclado numérico Teclado Flecha arriba 0x0007 0x0052 0xE048 83
Teclado/Teclado numérico Teclado numérico Bloq num y Borrar 0x0007 0x0053 0x0045
0xE045 *Nota 3
90
Teclado/Teclado numérico Teclado numérico Barra diagonal 0x0007 0x0054 0xE035 95
Teclado/Teclado numérico Teclado numérico Estrella 0x0007 0x0055 0x0037 100
Teclado/Teclado numérico Teclado numérico Guion 0x0007 0x0056 0x004A 105
Teclado/Teclado numérico Teclado numérico Más 0x0007 0x0057 0x004E 106
Teclado/Teclado numérico Teclado numérico ENTRAR 0x0007 0x0058 0xE01C 108
Teclado/Teclado numérico Teclado numérico 1 y Fin 0x0007 0x0059 0x004F 93
Teclado/Teclado numérico Teclado numérico 2 y flecha abajo 0x0007 0x005A 0x0050 98
Teclado/Teclado numérico Teclado numérico 3 y AvPág 0x0007 0x005B 0x0051 103
Teclado/Teclado numérico Teclado numérico 4 y flecha izquierda 0x0007 0x005C 0x004B 92
Teclado/Teclado numérico Teclado numérico 5 0x0007 0x005D 0x004C 97
Teclado/Teclado numérico Teclado numérico 6 y flecha derecha 0x0007 0x005E 0x004D 102
Teclado/Teclado numérico Teclado numérico 7 e Inicio 0x0007 0x005F 0x0047 91
Teclado/Teclado numérico Teclado numérico 8 y flecha arriba 0x0007 0x0060 0x0048 96
Teclado/Teclado numérico Teclado numérico 9 y RePág 0x0007 0x0061 0x0049 101
Teclado/Teclado numérico Teclado numérico 0 e insertar 0x0007 0x0062 0x0052 99
Teclado/Teclado numérico Teclado numérico Punto 0x0007 0x0063 0x0053 104
Teclado/Teclado numérico Teclado Barra diagonal no EE. UU. 0x0007 0x0064 0x0056 45
Teclado/Teclado numérico Teclado Aplicación 0x0007 0x0065 0xE05D 129
Teclado/Teclado numérico Teclado Encendido 0x0007 0x0066 0xE05E
Teclado/Teclado numérico Teclado numérico Igual 0x0007 0x0067 0x0059
Teclado/Teclado numérico Teclado F13 0x0007 0x0068 0x0064
Teclado/Teclado numérico Teclado F14 0x0007 0x0069 0x0065
Teclado/Teclado numérico Teclado F15 0x0007 0x006A 0x0066
Teclado/Teclado numérico Teclado F16 0x0007 0x006B 0x0067
Teclado/Teclado numérico Teclado F17 0x0007 0x006C 0x0068
Teclado/Teclado numérico Teclado F18 0x0007 0x006D 0x0069
Teclado/Teclado numérico Teclado F19 0x0007 0x006E 0x006A
Teclado/Teclado numérico Teclado F20 0x0007 0x006F 0x006B
Teclado/Teclado numérico Teclado F21 0x0007 0x0070 0x006C
Teclado/Teclado numérico Teclado F22 0x0007 0x0071 0x006D
Teclado/Teclado numérico Teclado F23 0x0007 0x0072 0x006E
Teclado/Teclado numérico Teclado F24 0x0007 0x0073 0x0076
Teclado/Teclado numérico Teclado numérico Coma 0x0007 0x0085 0x007E 107 *Nota 4
Teclado/Teclado numérico Teclado Internacional1 0x0007 0x0087 0x0073 56 *Nota 4, 5
Teclado/Teclado numérico Teclado Internacional2 0x0007 0x0088 0x0070 133 *Nota 5
Teclado/Teclado numérico Teclado Internacional3 0x0007 0x0089 0x007D 14 *Nota 5
Teclado/Teclado numérico Teclado Internacional4 0x0007 0x008A 0x0079 132 *Nota 5
Teclado/Teclado numérico Teclado Internacional5 0x0007 0x008B 0x007B 131 *Nota 5
Teclado/Teclado numérico Teclado Internacional6 0x0007 0x008C 0x005C
Teclado/Teclado numérico Teclado LANG1 0x0007 0x0090 0x0072 *Nota 6
0x00F2 *Nota 3, 6
Teclado/Teclado numérico Teclado LANG2 0x0007 0x0091 0x0071 *Nota 6
0x00F1 *Nota 3, 6
Teclado/Teclado numérico Teclado LANG3 0x0007 0x0092 0x0078
Teclado/Teclado numérico Teclado LANG4 0x0007 0x0093 0x0077
Teclado/Teclado numérico Teclado LANG5 0x0007 0x0094 0x0076
Teclado/Teclado numérico Teclado Control izquierdo 0x0007 0x00E0 0x001D 58
Teclado/Teclado numérico Teclado Mayús izquierda 0x0007 0x00E1 0x002A 44
Teclado/Teclado numérico Teclado Alt izquierda 0x0007 0x00E2 0x0038 60
Teclado/Teclado numérico Teclado GUI izquierda 0x0007 0x00E3 0xE05B 127
Teclado/Teclado numérico Teclado Control derecho 0x0007 0x00E4 0xE01D 64
Teclado/Teclado numérico Teclado Mayús derecha 0x0007 0x00E5 0x0036 57
Teclado/Teclado numérico Teclado Alt derecha 0x0007 0x00E6 0xE038 62
Teclado/Teclado numérico Teclado GUI derecha 0x0007 0x00E7 0xE05C 128
Consumidor Tecla Pista siguiente 0x000C 0x00B5 0xE019
Consumidor Tecla Pista anterior 0x000C 0x00B6 0xE010
Consumidor Stop 0x000C 0x00B7 0xE024
Consumidor Reproducir/Pausar 0x000C 0x00CD 0xE022
Consumidor Silenciar 0x000C 0x00E2 0xE020
Consumidor Incremento de volumen 0x000C 0x00E9 0xE030
Consumidor Disminución de volumen 0x000C 0x00EA 0xE02E
Consumidor AL Configuración de control de consumidor 0x000C 0x0183 0xE06D
Consumidor AL Lector de correo electrónico 0x000C 0x018A 0xE06C
Consumidor AL Calculadora 0x000C 0x0192 0xE021
Consumidor AL Explorador de máquina local 0x000C 0x0194 0xE06B
Consumidor AC Buscar 0x000C 0x0221 0xE065
Consumidor AC Inicio 0x000C 0x0223 0xE032
Consumidor AC Atrás 0x000C 0x0224 0xE06A
Consumidor CA Adelante 0x000C 0x0225 0xE069
Consumidor AC Detener 0x000C 0x0226 0xE068
Consumidor CA Actualizar 0x000C 0x0227 0xE067
Consumidor Marcadores de AC 0x000C 0x022A 0xE066

Notas:

  1. El código de tecla Pet Sisse emite con la pulsación de tecla Alt + Impr pant.
  2. El código de tecla Interse emite con la pulsación de tecla Control + Pausa.
  3. Tal y como se ve en los mensajes de teclado heredado.
  4. La tecla aparece en los teclados brasileños.
  5. La tecla aparece en los teclados japoneses.
  6. El código de tecla solo se emite en caso de liberar la tecla.

Marca de tecla extendida

La marca de tecla extendida indica si el mensaje de pulsación de tecla se originó en una de las teclas adicionales del teclado mejorado 101/102. Las teclas extendidas consisten en las teclas ALT y CTRL en el lado derecho del teclado; las teclas INSERT, SUPR, INICIO, FIN, RE PÁG., AV PÁG. y las teclas de flecha de los clústeres a la izquierda del teclado numérico; la tecla BLOQ NUM; la tecla INTER (CTRL+PAUSA); la tecla IMPR PANT, y las teclas de división (/) y ENTRAR del teclado numérico. La tecla MAYÚS de la derecha no se considera una tecla extendida; en su lugar, tiene un código de tecla independiente.

Si se especifica, el código de tecla consta de una secuencia de dos bytes, en la que el primer byte tiene un valor de 0xE0.

Código de contexto

El código de contexto indica si la tecla ALT se había pulsado cuando se generó el mensaje de pulsación de tecla. El código es 1 si la tecla ALT estaba abajo y 0 si estaba arriba.

Marca de estado de tecla anterior

La marca de estado de tecla anterior indica si la tecla que generó el mensaje de pulsación de tecla estaba arriba o abajo anteriormente. Es 1 si la tecla anteriormente estaba abajo y 0 si la tecla anteriormente estaba arriba. Puede usar esta marca para identificar los mensajes de pulsación de tecla generados por la característica de repetición automática del teclado. Esta marca se establece en 1 para los mensajes de pulsación de tecla WM_KEYDOWN y WM_SYSKEYDOWN generados por la característica de repetición automática. Siempre se establece en 1 para los mensajes WM_KEYUP y WM_SYSKEYUP.

Marca de estado de transición

La marca de estado de transición indica si presionar una tecla o soltarla generó el mensaje de pulsación de tecla. Esta marca siempre se establece en 0 para los mensajes WM_KEYDOWN y WM_SYSKEYDOWN; siempre se establece en 1 para los mensajes WM_KEYUP y WM_SYSKEYUP.

Mensajes de caracteres

Los mensajes de pulsación de tecla proporcionan mucha información sobre las pulsaciones de tecla, pero no proporcionan códigos de caracteres para las pulsaciones de teclas de caracteres. Para recuperar los códigos de caracteres, una aplicación debe incluir la función TranslateMessage en su bucle de mensajes de subproceso. TranslateMessage pasa un mensaje WM_KEYDOWN o WM_SYSKEYDOWN al diseño del teclado. El diseño examina el código de tecla virtual del mensaje y, si corresponde a una tecla de carácter, proporciona el código de carácter equivalente (teniendo en cuenta el estado de las teclas MAYÚS y BLOQ MAYÚS). Después, genera un mensaje de carácter que incluye el código de caracteres y coloca el mensaje en la parte superior de la cola de mensajes. La siguiente iteración del bucle de mensajes quita el mensaje de carácter de la cola y lo envía al procedimiento de ventana adecuado.

En esta sección se describen los temas siguientes:

Mensajes de caracteres que no son del sistema

Un procedimiento de ventana puede recibir los siguientes mensajes de caracteres: WM_CHAR, WM_DEADCHAR, WM_SYSCHAR, WM_SYSDEADCHAR y WM_UNICHAR. La función TranslateMessage genera un mensaje WM_CHAR o WM_DEADCHAR cuando procesa un mensaje WM_KEYDOWN. Del mismo modo, genera un mensaje WM_SYSCHAR o WM_SYSDEADCHAR cuando procesa un mensaje WM_SYSKEYDOWN.

Una aplicación que procesa la entrada de teclado normalmente omite todos los mensajes excepto WM_CHAR y WM_UNICHAR, y pasa los demás mensajes a la función DefWindowProc. Tenga en cuenta que WM_CHAR usa UTF-16 (formato de transformación Unicode de 16 bits) o el juego de caracteres ANSI, mientras que WM_UNICHAR siempre usa UTF-32 (formato de transformación Unicode de 32 bits). El sistema usa los mensajes WM_SYSCHAR y WM_SYSDEADCHAR para implementar la mneumónica de menús.

El parámetro wParam de todos los mensajes de caracteres contiene el código de carácter de la tecla de carácter que se presionó. El valor del código de carácter depende de la clase de ventana de la ventana que recibe el mensaje. Si se usó la versión Unicode de la función RegisterClass para registrar la clase de ventana, el sistema proporciona caracteres Unicode a todas las ventanas de esa clase. De lo contrario, el sistema proporciona códigos de carácter ANSI. Para obtener más información, vea Registro de las clases de ventana y Uso de páginas de código UTF-8 en aplicaciones de Windows.

El contenido del parámetro lParam de un mensaje de caracteres es idéntico al contenido del parámetro lParam del mensaje de tecla abajo traducido para generar el mensaje de caracteres. Para obtener información, vea Marcas de mensajes de pulsación de tecla.

Mensajes de caracteres inactivos

Algunos teclados que no son en inglés contienen teclas de caracteres que no se espera que generen caracteres por sí mismas. En su lugar, se usan para agregar un diacrítico al carácter generado por la pulsación de tecla posterior. Estas teclas se denominan teclas inactivas. La tecla de circunflejo en un teclado alemán es un ejemplo de tecla inactiva. Para escribir el carácter que consiste en una "o" con un circunflejo, un usuario alemán escribiría la tecla de circunflejo seguida de la tecla "o". La ventana con el foco del teclado recibiría la siguiente secuencia de mensajes:

  1. WM_KEYDOWN
  2. WM_DEADCHAR
  3. WM_KEYUP
  4. WM_KEYDOWN
  5. WM_CHAR
  6. WM_KEYUP

TranslateMessage genera el mensaje WM_DEADCHAR cuando procesa el mensaje WM_KEYDOWN de una tecla inactiva. Si bien el parámetro wParam del mensaje WM_DEADCHAR contiene el código de carácter del signo diacrítico de la tecla inactiva, una aplicación normalmente omite el mensaje. En su lugar, procesa el mensaje WM_CHAR generado por la pulsación de tecla posterior. El parámetro wParam del mensaje WM_CHAR contiene el código de carácter de la letra con el diacrítico. Si la pulsación de tecla posterior genera un carácter que no se puede combinar con un diacrítico, el sistema genera dos mensajes WM_CHAR. El parámetro wParam del primero contiene el código de carácter del diacrítico; el parámetro wParam del segundo contiene el código de carácter de la tecla de carácter posterior.

La función TranslateMessage genera el mensaje WM_SYSDEADCHAR cuando procesa el mensaje WM_SYSKEYDOWN de una tecla inactiva del sistema (una tecla inactiva que se presiona en combinación con la tecla ALT). Normalmente, una aplicación omite el mensaje WM_SYSDEADCHAR.

Estado de la tecla

Al procesar un mensaje de teclado, es posible que una aplicación tenga que determinar el estado de otra tecla además de la que generó el mensaje actual. Por ejemplo, una aplicación de procesamiento de texto que permite al usuario presionar MAYÚS+FIN para seleccionar un bloque de texto debe comprobar el estado de la tecla MAYÚS siempre que reciba un mensaje de pulsación de tecla de la tecla FIN. La aplicación puede usar la función GetKeyState para determinar el estado de una tecla virtual en el momento en que se generó el mensaje actual; puede usar la función GetAsyncKeyState para recuperar el estado actual de una tecla virtual.

El diseño del teclado mantiene una lista de nombres. El nombre de una tecla que genera un solo carácter es el mismo que el carácter que genera la tecla. El nombre de una tecla que no es de carácter, como TAB y ENTRAR, se almacena como una cadena de caracteres. Una aplicación puede recuperar el nombre de cualquier tecla del controlador de dispositivo llamando a la función GetKeyNameText.

Traducciones de las pulsaciones de teclas y caracteres

El sistema incluye varias funciones de propósito especial que traducen los códigos de tecla, códigos de carácter y códigos de tecla virtual proporcionados por varios mensajes de pulsación de tecla. Estas funciones incluyen MapVirtualKey, ToAscii, ToUnicode y VkKeyScan.

Además, Microsoft Rich Edit 3.0 admite el IME HexToUnicode, que permite al usuario convertir entre caracteres hexadecimales y Unicode mediante teclas de acceso rápido. Esto significa que, cuando Microsoft Rich Edit 3.0 se incorpora a una aplicación, la aplicación heredará las características del IME HexToUnicode.

Compatibilidad con teclas de acceso rápido

Una tecla de acceso rápido es una combinación de teclas que genera un mensaje WM_HOTKEY, un mensaje que el sistema coloca en la parte superior de la cola de mensajes de un subproceso, omitiendo los mensajes existentes de la cola. Las aplicaciones usan teclas de acceso rápido para obtener la entrada de teclado de alta prioridad del usuario. Por ejemplo, al definir una tecla de acceso rápido que consiste en la combinación de teclas CTRL+C, una aplicación puede permitir al usuario cancelar una operación larga.

Para definir una tecla de acceso rápido, una aplicación llama a la función RegisterHotKey, especificando la combinación de teclas que genera el mensaje WM_HOTKEY, el identificador de la ventana que va a recibir el mensaje y el identificador de la tecla de acceso rápido. Cuando el usuario presiona la tecla de acceso rápido, se coloca un mensaje WM_HOTKEY en la cola de mensajes del subproceso que creó la ventana. El parámetro wParam del mensaje contiene el identificador de la tecla de acceso rápido. La aplicación puede definir varias teclas de acceso rápido para un subproceso, pero cada tecla de acceso rápido del subproceso debe tener un identificador único. Antes de que finalice la aplicación, debe usar la función UnregisterHotKey para destruir la tecla de acceso rápido.

Las aplicaciones pueden usar un control de tecla de acceso rápido para facilitar que el usuario elija una tecla de acceso rápido. Los controles de tecla de acceso rápido se suelen usar para definir una tecla de acceso rápido que activa una ventana; no usan las funciones RegisterHotKey y UnregisterHotKey. En su lugar, una aplicación que usa un control de tecla de acceso rápido suele enviar el mensaje WM_SETHOTKEY para establecer la tecla de acceso rápido. Siempre que el usuario presiona la tecla de acceso rápido, el sistema envía un mensaje WM_SYSCOMMAND especificando SC_HOTKEY. Para obtener más información sobre los controles de tecla de acceso rápido, vea "Uso de los controles de tecla de acceso rápido" en Controles de tecla de acceso rápido.

Teclas del teclado para la navegación y otras funciones

Windows proporciona compatibilidad con teclados con teclas especiales para funciones del explorador, funciones multimedia, inicio de aplicaciones y administración de energía. WM_APPCOMMAND admite las teclas de teclado adicionales. Además, la función ShellProc se modifica para admitir las teclas de teclado adicionales.

Es poco probable que una ventana secundaria de una aplicación de componente pueda implementar directamente comandos para estas teclas de teclado adicionales. Por lo tanto, cuando se presione una de estas teclas, DefWindowProc enviará un mensaje WM_APPCOMMAND a una ventana. DefWindowProc también enviará el mensaje WM_APPCOMMAND a su ventana primaria. Esto es similar a la forma en que se invocan los menús contextuales con el botón derecho del mouse, que es que DefWindowProc envía un mensaje WM_CONTEXTMENU al hacer clic con el botón derecho y lo propaga a su elemento primario. Además, si DefWindowProc recibe un mensaje WM_APPCOMMAND para una ventana de nivel superior, llamará a un enlace de shell con código HSHELL_APPCOMMAND.

Windows también admite el Explorador de Microsoft IntelliMouse, que es un mouse con cinco botones. Los dos botones adicionales admiten la navegación hacia delante y hacia atrás del explorador. Para obtener más información, vea XBUTTON.

Simulación de entradas

Para simular una serie ininterrumpida de eventos de entrada de usuario, use la función SendInput. La función acepta tres parámetros. El primer parámetro, cInputs, indica el número de eventos de entrada que se simularán. El segundo parámetro, rgInputs, es una matriz de estructuras INPUT, cada una de las cuales describe un tipo de evento de entrada e información adicional sobre ese evento. El último parámetro, cbSize, acepta el tamaño de la estructura INPUT en bytes.

La función SendInput funciona insertando una serie de eventos de entrada simulados en el flujo de entrada de un dispositivo. El efecto es similar a llamar repetidamente a la función keybd_event o mouse_event, salvo que el sistema garantiza que ningún otro evento de entrada se entrometa con los eventos simulados. Cuando se completa la llamada, el valor devuelto indica el número de eventos de entrada que se han reproducido correctamente. Si este valor es cero, se bloqueó la entrada.

La función SendInput no restablece el estado actual del teclado. Por lo tanto, si el usuario tiene alguna tecla presionada al llamar a esta función, podría interferir con los eventos que genera esta función. Si le preocupa la posible interferencia, compruebe el estado del teclado con la función GetAsyncKeyState y corrija según sea necesario.

Idiomas, configuraciones regionales y diseños de teclado

Un idioma es un idioma natural, como inglés, francés y japonés. Un subidioma es una variante de un idioma natural que se habla en una región geográfica específica, como los dialectos ingleses hablados en el Reino Unido y Estados Unidos. Las aplicaciones usan valores denominados identificadores de idioma para identificar de forma única los idiomas y subidiomas.

Las aplicaciones suelen usar configuraciones regionales para establecer el idioma en el que se procesa la entrada y la salida. Establecer la configuración regional del teclado, por ejemplo, afecta a los valores de carácter que genera el teclado. Establecer la configuración regional de la pantalla o la impresora afecta a los glifos que se muestran o imprimen. Las aplicaciones establecen la configuración regional de un teclado cargando y usando diseños de teclado. Establecen la configuración regional de una pantalla o impresora seleccionando una fuente que admita la configuración regional especificada.

Un diseño de teclado no solo especifica la posición física de las teclas en el teclado, sino que también determina los valores de carácter que se generan presionando esas teclas. Cada diseño identifica el idioma de entrada actual y determina qué valores de carácter se generan mediante las teclas y combinaciones de teclas.

Cada diseño de teclado tiene un identificador correspondiente que identifica el diseño y el idioma. La palabra inferior del identificador es un identificador de idioma. La palabra superior es un identificador de dispositivo que especifica el diseño físico o bien es cero, lo que indica un diseño físico predeterminado. El usuario puede asociar cualquier idioma de entrada con un diseño físico. Por ejemplo, un usuario que habla inglés y que trabaja muy ocasionalmente en francés puede establecer el idioma de entrada del teclado en francés sin cambiar el diseño físico del teclado. Esto significa que el usuario puede escribir texto en francés con el diseño en inglés conocido.

Por lo general, no se espera que las aplicaciones manipulen los idiomas de entrada directamente. En su lugar, el usuario configura combinaciones de idioma y diseño y, después, cambia entre ellas. Cuando el usuario hace clic en un texto marcado con otro idioma, la aplicación llama a la función ActivateKeyboardLayout a fin de activar el diseño predeterminado del usuario para ese idioma. Si el usuario edita texto en un idioma que no está en la lista activa, la aplicación puede llamar a la función LoadKeyboardLayout con el idioma para obtener un diseño basado en ese idioma.

La función ActivateKeyboardLayout establece el idioma de entrada de la tarea actual. El parámetro hkl puede ser el identificador del diseño del teclado o un identificador de idioma extendido de cero. Los identificadores del diseño de teclado se pueden obtener de la función LoadKeyboardLayout o GetKeyboardLayoutList. Los valores HKL_NEXT y HKL_PREV también se pueden usar para seleccionar el teclado siguiente o anterior.

La función GetKeyboardLayoutName recupera el nombre del diseño de teclado activo para el subproceso que realiza la llamada. Si una aplicación crea el diseño activo mediante la función LoadKeyboardLayout, GetKeyboardLayoutName recupera la misma cadena usada para crear el diseño. De lo contrario, la cadena es el identificador de idioma principal correspondiente a la configuración regional del diseño activo. Esto significa que la función no tiene que diferenciar necesariamente entre diseños diferentes con el mismo idioma principal, por lo que no puede devolver información específica sobre el idioma de entrada. Sin embargo, la función GetKeyboardLayout se puede usar para determinar el idioma de entrada.

La función LoadKeyboardLayout carga un diseño de teclado y hace que el diseño esté disponible para el usuario. Las aplicaciones pueden activar el diseño inmediatamente para el subproceso actual mediante el valor KLF_ACTIVATE. Una aplicación puede usar el valor KLF_REORDER para reordenar los diseños sin especificar también el valor KLF_ACTIVATE. Las aplicaciones siempre deben usar el valor KLF_SUBSTITUTE_OK al cargar diseños de teclado para asegurarse de que la preferencia del usuario, si existe, esté seleccionada.

Para obtener compatibilidad multilingüe, la función LoadKeyboardLayout proporciona las marcas KLF_REPLACELANG y KLF_NOTELLSHELL. La marca KLF_REPLACELANG dirige la función para reemplazar un diseño de teclado existente sin cambiar el idioma. Intentar reemplazar un diseño existente con el mismo identificador de idioma pero sin especificar KLF_REPLACELANG es un error. La marca KLF_NOTELLSHELL impide que la función notifique al shell cuándo se agrega o se reemplaza un diseño de teclado. Esto es útil para las aplicaciones que agregan varios diseños en una serie consecutiva de llamadas. Esta marca se debe usar en todas las llamadas excepto la última.

La función UnloadKeyboardLayout está restringida en que no puede descargar el idioma de entrada predeterminado del sistema. Esto garantiza que el usuario siempre tenga un diseño disponible para escribir texto con el mismo juego de caracteres que usa el shell y el sistema de archivos.