Visão geral da entrada do teclado

Os aplicativos devem aceitar a entrada do usuário por meio do teclado, bem como do mouse. Um aplicativo recebe a entrada de teclado na forma de mensagens postadas nas janelas.

Modelo de entrada de teclado

O sistema fornece suporte de teclado independente de dispositivo para os aplicativos instalando um driver de dispositivo de teclado apropriado para o teclado atual. O sistema fornece suporte de teclado independente de idioma usando o layout de teclado específico do idioma atualmente selecionado pelo usuário ou pelo aplicativo. O driver de dispositivo de teclado recebe códigos de verificação do teclado, que são enviados para o layout do teclado, no qual são convertidos em mensagens e postados nas janelas apropriadas no seu aplicativo.

Um valor exclusivo chamado código de verificação, um identificador dependente de dispositivo para a tecla no teclado, é atribuído a cada tecla de um teclado. Um teclado gera dois códigos de verificação quando o usuário digita uma tecla: um quando o usuário pressiona a tecla e outro quando o usuário solta a tecla.

O driver de dispositivo de teclado interpreta um código de verificação e o converte (mapeia) em um código de tecla virtual, um valor independente de dispositivo definido pelo sistema que identifica a finalidade de uma tecla. Depois de converter um código de verificação, o layout do teclado cria uma mensagem que inclui o código de verificação, o código de tecla virtual e outras informações sobre o pressionamento de tecla e, em seguida, coloca a mensagem na fila de mensagens do sistema. O sistema remove a mensagem da fila de mensagens do sistema e a posta na fila de mensagens do thread apropriado. Por fim, o loop de mensagens do thread remove a mensagem e a transmite ao procedimento de janela apropriado para processamento. A figura a seguir ilustra o modelo de entrada de teclado.

keyboard input processing model

Foco e ativação do teclado

O sistema posta as mensagens do teclado na fila de mensagens do thread em primeiro plano que criou a janela com o foco do teclado. O foco do teclado é uma propriedade temporária de uma janela. O sistema compartilha o teclado entre todas as janelas na tela, deslocando o foco do teclado, na direção do usuário, de uma janela para outra. A janela que tem o foco do teclado recebe (da fila de mensagens do thread que a criou) todas as mensagens do teclado até que o foco mude para outra janela.

Um thread pode chamar a função GetFocus para determinar qual das janelas (se houver) atualmente tem o foco do teclado. Um thread pode dar o foco do teclado a uma das janelas chamando a função SetFocus. Quando o foco do teclado muda de uma janela para outra, o sistema envia uma mensagem WM_KILLFOCUS para a janela que perdeu o foco e envia uma mensagem WM_SETFOCUS para a janela que obteve o foco.

O conceito de foco do teclado está relacionado ao da janela ativa. A janela ativa é a janela de nível superior com a qual o usuário está trabalhando no momento. A janela com o foco do teclado é a janela ativa ou uma janela filho da janela ativa. Para ajudar o usuário a identificar a janela ativa, o sistema a coloca na parte superior da ordem Z e realça a barra de título (se houver) e a borda dela.

O usuário pode ativar uma janela de nível superior clicando nela, selecionando-a com uma combinação de teclas ALT+TAB ou ALT+ESC ou selecionando-a na Lista de Tarefas. Um thread pode ativar uma janela de nível superior usando a função SetActiveWindow. Ele pode determinar se uma janela de nível superior criada está ativa usando a função GetActiveWindow.

Quando uma janela é desativada e outra ativada, o sistema envia a mensagem WM_ACTIVATE. A palavra de ordem inferior do parâmetro wParam será zero se a janela estiver sendo desativada e diferente de zero se estiver sendo ativada. Quando o procedimento de janela padrão recebe a mensagem WM_ACTIVATE, ele define o foco do teclado como a janela ativa.

Para impedir que eventos de entrada de teclado e do mouse cheguem aos aplicativos, use BlockInput. Observe que a função BlockInput não vai interferir na tabela assíncrona de estado de entrada de teclado. Isso significa que uma chamada à função SendInput enquanto a entrada está bloqueada altera a tabela assíncrona de estado de entrada de teclado.

Mensagens de pressionamento de tecla

O pressionamento de uma tecla faz com que uma mensagem WM_KEYDOWN ou WM_SYSKEYDOWN seja colocada na fila de mensagens do thread anexada à janela que tem o foco do teclado. A liberação de uma tecla faz com que uma mensagem WM_KEYUP ou WM_SYSKEYUP seja colocada na fila.

As mensagens de tecla liberada e tecla pressionada normalmente ocorrem em pares, mas se o usuário mantiver pressionada uma tecla por tempo suficiente para iniciar o recurso de repetição automática do teclado, o sistema vai gerar uma série de mensagens WM_KEYDOWN ou WM_SYSKEYDOWN em uma linha. Em seguida, ele gera uma mensagem individual WM_KEYUP ou WM_SYSKEYUP quando o usuário libera a tecla.

Esta seção contém os seguintes tópicos:

Pressionamentos de teclas do sistema e que não são do sistema

O sistema faz uma distinção entre pressionamentos de teclas do sistema e pressionamentos de tecla que não são do sistema. Os pressionamentos de teclas do sistema produzem as mensagens de pressionamento de teclas do sistema WM_SYSKEYDOWN e WM_SYSKEYUP. Os pressionamentos de teclas que não são do sistema produzem as mensagens de pressionamento de tecla que não são do sistema WM_KEYDOWN e WM_KEYUP.

Se o procedimento de janela precisar processar uma mensagem de pressionamento de tecla do sistema, verifique se, depois de processar a mensagem, o procedimento a transmite para a função DefWindowProc. Caso contrário, todas as operações do sistema que envolvem a tecla ALT serão desabilitadas sempre que a janela tiver o foco do teclado. Ou seja, o usuário não poderá acessar os menus da janela nem o menu Sistema ou usar a combinação de teclas ALT+ESC ou ALT+TAB para ativar outra janela.

As mensagens de pressionamento de tecla do sistema são usadas principalmente pelo sistema e não por um aplicativo. O sistema as usa para fornecer a interface de teclado interna para os menus e para permitir que o usuário controle a janela que ficará ativa. As mensagens de pressionamento de tecla do sistema são geradas quando o usuário digita uma tecla em combinação com a tecla ALT ou quando o usuário digita uma tecla e nenhuma janela tem o foco do teclado (por exemplo, quando o aplicativo ativo está minimizado). Nesse caso, as mensagens são postadas na fila de mensagens anexada à janela ativa.

As mensagens de pressionamento de tecla que não são do sistema são usadas pelas janelas do aplicativo. A função DefWindowProc não executa nenhuma ação com elas. Um procedimento de janela pode descartar qualquer mensagem de pressionamento de tecla que não é do sistema que não seja necessária.

Descrição dos códigos de tecla virtual

O parâmetro wParam de uma mensagem de pressionamento de tecla contém o código de tecla virtual da tecla que foi pressionada ou liberada. Um procedimento de janela processa ou ignora uma mensagem de pressionamento de tecla, dependendo do valor do código de tecla virtual.

Um procedimento de janela típico processa apenas um pequeno subconjunto das mensagens de pressionamento de tecla que ele recebe e ignora o restante. Por exemplo, um procedimento de janela só pode processar mensagens de pressionamento de tecla WM_KEYDOWN e somente aquelas que contêm códigos de tecla virtual para as teclas de movimento do cursor, teclas de deslocamento (também chamadas de teclas de controle) e teclas de função. Um procedimento de janela típico não processa mensagens de pressionamento de tecla por meio de teclas de caracteres. Em vez disso, ele usa a função TranslateMessage para converter a mensagem em mensagens de caracteres. Para obter mais informações sobre TranslateMessage e as mensagens de caracteres, confira Mensagens de caracteres.

Sinalizadores de mensagem de pressionamento de tecla

O parâmetro lParam de uma mensagem de pressionamento de tecla contém informações adicionais sobre o pressionamento de tecla que gerou a mensagem. Essas informações incluem a contagem de repetição, o código de verificação, o sinalizador de tecla estendida, o código de contexto, o sinalizador de estado anterior da tecla e o sinalizador de estado de transição. A ilustração a seguir mostra os locais desses sinalizadores e valores no parâmetro lParam.

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

Um aplicativo pode usar os valores a seguir para obter os sinalizadores de pressionamento de tecla da palavra de ordem superior do lParam.

Valor Descrição
KF_EXTENDED
0x0100
Processa o sinalizador de tecla estendida.
KF_DLGMODE
0x0800
Processa o sinalizador de modo de caixa de diálogo, que indica se uma caixa de diálogo está ativa.
KF_MENUMODE
0x1000
Processa o sinalizador de modo de menu, que indica se um menu está ativo.
KF_ALTDOWN
0x2000
Processa o sinalizador de código de contexto.
KF_REPEAT
0x4000
Processa o sinalizador de estado anterior da tecla.
KF_UP
0x8000
Processa o sinalizador de estado de transição.

Exemplo de código:

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;

Contagem repetida

Você pode verificar a contagem de repetição para determinar se uma mensagem de pressionamento de tecla representa mais de um pressionamento de tecla. O sistema incrementa a contagem quando o teclado gera mensagens WM_KEYDOWN ou WM_SYSKEYDOWN mais rápido do que um aplicativo pode processá-las. Em geral, isso ocorre quando o usuário pressiona uma tecla por tempo suficiente para iniciar o recurso de repetição automática do teclado. Em vez de preencher a fila de mensagens do sistema com as mensagens de tecla resultantes, o sistema combina as mensagens em uma só mensagem de tecla pressionada e incrementa a contagem de repetição. A liberação de uma tecla não pode iniciar o recurso de repetição automática. Portanto, a contagem de repetição para mensagens WM_KEYUP e WM_SYSKEYUP é sempre definida como 1.

Códigos de verificação

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

O código de verificação é o valor que o sistema gera quando o usuário pressiona uma tecla. É um valor que identifica a tecla pressionada independentemente do layout de teclado ativo, em oposição ao caractere representado pela tecla. Um aplicativo normalmente ignora os códigos de verificação. Em vez disso, ele usa os códigos de chave virtual para interpretar mensagens de pressionamento de tecla.

Os teclados modernos estão usando a especificação Human Interface Devices (HID) para se comunicar com um computador. Driver de teclado converte valores de uso HID relatados enviados do teclado para verificar os códigos e os repassa para aplicativos.

Observação

Embora os códigos de chave virtual sejam normalmente mais úteis para aplicativos de desktop, os códigos de verificação podem ser necessários em casos específicos em que você precisa saber qual tecla é pressionada, independentemente do layout atual do teclado. Por exemplo, as ligações de teclas WASD (W está para cima, A é para a esquerda, S está para baixo e D é para a direita) para jogos, que garantem uma formação de teclas consistente em layouts de teclado QWERTY dos EUA ou AZERTY francês de teclado.

A tabela a seguir lista o conjunto de códigos de verificação como atualmente reconhecido pelo Windows. Os valores da página de uso HID/ID de uso HID/Nome de uso HID fazem referência ao documento Tabelas de uso HID. Os valores Localização da chave fazem referência à imagem de teclado anterior.

O código Scan 1 Make é entregue em mensagens WM_KEYDOWN/WM_KEYUP/WM_SYSKEYDOWN/WM_SYSKEYUP e WM_INPUT.

Nome da página de uso do HID Nome de uso do HID Página de uso do HID ID de uso do HID Scan 1 Make Localização chave
Desktop genérico Desligamento do sistema 0x0001 0x0081 0xE05E
Desktop genérico Suspensão do sistema 0x0001 0x0082 0xE05F
Desktop genérico Ativação do sistema 0x0001 0x0083 0xE063
Teclado/Teclado ErrorRollOver 0x0007 0x0001 0x00FF
Teclado/Teclado Teclado A 0x0007 0x0004 0x001E 31
Teclado/Teclado Teclado B 0x0007 0x0005 0x0030 50
Teclado/Teclado Teclado C 0x0007 0x0006 0x002E 48
Teclado/Teclado Teclado D 0x0007 0x0007 0x0020 33
Teclado/Teclado Teclado E 0x0007 0x0008 0x0012 19
Teclado/Teclado Teclado F 0x0007 0x0009 0x0021 34
Teclado/Teclado Teclado G 0x0007 0x000A 0x0022 35
Teclado/Teclado Teclado H 0x0007 0x000B 0x0023 36
Teclado/Teclado Teclado I 0x0007 0x000C 0x0017 24
Teclado/Teclado Teclado J 0x0007 0x000D 0x0024 37
Teclado/Teclado Teclado K 0x0007 0x000E 0x0025 38
Teclado/Teclado Teclado L 0x0007 0x000F 0x0026 39
Teclado/Teclado Teclado M 0x0007 0x0010 0x0032 52
Teclado/Teclado Teclado N 0x0007 0x0011 0x0031 51
Teclado/Teclado Teclado O 0x0007 0x0012 0x0018 25
Teclado/Teclado Teclado P 0x0007 0x0013 0x0019 26
Teclado/Teclado Teclado Q 0x0007 0x0014 0x0010 17
Teclado/Teclado Teclado R 0x0007 0x0015 0x0013 20
Teclado/Teclado Teclado S 0x0007 0x0016 0x001F 32
Teclado/Teclado Teclado T 0x0007 0x0017 0x0014 21
Teclado/Teclado Teclado U 0x0007 0x0018 0x0016 23
Teclado/Teclado Teclado V 0x0007 0x0019 0x002F 49
Teclado/Teclado Teclado W 0x0007 0x001A 0x0011 18
Teclado/Teclado Teclado X 0x0007 0x001B 0x002D 47
Teclado/Teclado Teclado Y 0x0007 0x001C 0x0015 22
Teclado/Teclado Teclado Z 0x0007 0x001D 0x002C 46
Teclado/Teclado Teclado 1 e Bang 0x0007 0x001E 0x0002 2
Teclado/Teclado Teclado 2 e AT 0x0007 0x001F 0x0003 3
Teclado/Teclado Teclado 3 e hash 0x0007 0x0020 0x0004 4
Teclado/Teclado Teclado 4 e dólar 0x0007 0x0021 0x0005 5
Teclado/Teclado Teclado 5 e por cento 0x0007 0x0022 0x0006 6
Teclado/Teclado Teclado 6 e caret 0x0007 0x0023 0x0007 7
Teclado/Teclado Teclado 7 e E comercial 0x0007 0x0024 0x0008 8
Teclado/Teclado Teclado 8 e estrela 0x0007 0x0025 0x0009 9
Teclado/Teclado Teclado 9 e colchete esquerdo 0x0007 0x0026 0x000A 10
Teclado/Teclado Teclado 0 e colchete direito 0x0007 0x0027 0x000B 11
Teclado/Teclado Retorno enter do teclado 0x0007 0x0028 0x001C 43
Teclado/Teclado Escape do teclado 0x0007 0x0029 0x0001 110
Teclado/Teclado Excluir teclado 0x0007 0x002A 0x000E 15
Teclado/Teclado Tab do teclado 0x0007 0x002B 0x000F 16
Teclado/Teclado Barra de espaço do teclado 0x0007 0x002C 0x0039 61
Teclado/Teclado Traço e sublinhado do teclado 0x0007 0x002D 0x000C 12
Teclado/Teclado Igual e mais do teclado 0x0007 0x002E 0x000D 13
Teclado/Teclado Chave esquerda do teclado 0x0007 0x002F 0x001A 27
Teclado/Teclado Chave direita do teclado 0x0007 0x0030 0x001B 28
Teclado/Teclado Pipe e barra do teclado 0x0007 0x0031 0x002B 29
Teclado/Teclado Teclado fora dos EUA 0x0007 0x0032 0x002B 42
Teclado/Teclado Dois pontos e ponto e vírgula do teclado 0x0007 0x0033 0x0027 40
Teclado/Teclado Apóstrofo de teclado e aspas duplas 0x0007 0x0034 0x0028 41
Teclado/Teclado Til e acento agudo do teclado 0x0007 0x0035 0x0029 1
Teclado/Teclado Vírgula do teclado 0x0007 0x0036 0x0033 53
Teclado/Teclado Ponto do teclado 0x0007 0x0037 0x0034 54
Teclado/Teclado Ponto de interrogação do teclado 0x0007 0x0038 0x0035 55
Teclado/Teclado Maiúscula do teclado 0x0007 0x0039 0x003A 30
Teclado/Teclado Teclado F1 0x0007 0x003A 0x003B 112
Teclado/Teclado Teclado F2 0x0007 0x003B 0x003C 113
Teclado/Teclado Teclado F3 0x0007 0x003C 0x003D 114
Teclado/Teclado Teclado F4 0x0007 0x003D 0x003E 115
Teclado/Teclado Teclado F5 0x0007 0x003E 0x003F 116
Teclado/Teclado Teclado F6 0x0007 0x003F 0x0040 117
Teclado/Teclado Teclado F7 0x0007 0x0040 0x0041 118
Teclado/Teclado Teclado F8 0x0007 0x0041 0x0042 119
Teclado/Teclado Teclado F9 0x0007 0x0042 0x0043 120
Teclado/Teclado Teclado F10 0x0007 0x0043 0x0044 121
Teclado/Teclado Teclado F11 0x0007 0x0044 0x0057 122
Teclado/Teclado Teclado F12 0x0007 0x0045 0x0058 123
Teclado/Teclado PrintScreen do teclado 0x0007 0x0046 0xE037
0x0054 *Nota 1
124
Teclado/Teclado Bloqueio de rolagem do teclado 0x0007 0x0047 0x0046 125
Teclado/Teclado Pausa do teclado 0x0007 0x0048 0xE11D45
0xE046 *Nota 2
0x0045 *Nota 3
126
Teclado/Teclado Inserção do teclado 0x0007 0x0049 0xE052 75
Teclado/Teclado Página inicial do teclado 0x0007 0x004A 0xE047 80
Teclado/Teclado PageUp do teclado 0x0007 0x004B 0xE049 85
Teclado/Teclado Excluir daqui para a frente do teclado 0x0007 0x004C 0xE053 76
Teclado/Teclado End do teclado 0x0007 0x004D 0xE04F 81
Teclado/Teclado PageDown do teclado 0x0007 0x004E 0xE051 86
Teclado/Teclado Seta para a direita do teclado 0x0007 0x004F 0xE04D 89
Teclado/Teclado Seta para a esquerda do teclado 0x0007 0x0050 0xE04B 79
Teclado/Teclado DownArrow do teclado 0x0007 0x0051 0xE050 84
Teclado/Teclado UpArrow do Teclado 0x0007 0x0052 0xE048 83
Teclado/Teclado Teclado Num Lock e Limpar 0x0007 0x0053 0x0045
0xE045 *Nota 3
90
Teclado/Teclado Barra direta do teclado 0x0007 0x0054 0xE035 95
Teclado/Teclado Estrela do teclado 0x0007 0x0055 0x0037 100
Teclado/Teclado Traço do teclado 0x0007 0x0056 0x004A 105
Teclado/Teclado Mais do teclado 0x0007 0x0057 0x004E 106
Teclado/Teclado ENTER do teclado 0x0007 0x0058 0xE01C 108
Teclado/Teclado Teclado 1 e End 0x0007 0x0059 0x004F 93
Teclado/Teclado Teclado 2 e seta para baixo 0x0007 0x005A 0x0050 98
Teclado/Teclado Teclado 3 e PageDn 0x0007 0x005B 0x0051 103
Teclado/Teclado Teclado 4 e seta para a esquerda 0x0007 0x005C 0x004B 92
Teclado/Teclado Teclado 5 0x0007 0x005D 0x004C 97
Teclado/Teclado Teclado 6 e seta para a direita 0x0007 0x005E 0x004D 102
Teclado/Teclado Teclado 7 e Home 0x0007 0x005F 0x0047 91
Teclado/Teclado Teclado 8 e seta para cima 0x0007 0x0060 0x0048 96
Teclado/Teclado Teclado 9 e PageUp 0x0007 0x0061 0x0049 101
Teclado/Teclado Teclado 0 e Insert 0x0007 0x0062 0x0052 99
Teclado/Teclado Ponto do teclado 0x0007 0x0063 0x0053 104
Teclado/Teclado Barra de barra do teclado fora dos EUA 0x0007 0x0064 0x0056 45
Teclado/Teclado Aplicativo de teclado 0x0007 0x0065 0xE05D 129
Teclado/Teclado Potência do teclado 0x0007 0x0066 0xE05E
Teclado/Teclado Igual do teclado 0x0007 0x0067 0x0059
Teclado/Teclado Teclado F13 0x0007 0x0068 0x0064
Teclado/Teclado Teclado F14 0x0007 0x0069 0x0065
Teclado/Teclado Teclado F15 0x0007 0x006A 0x0066
Teclado/Teclado Teclado F16 0x0007 0x006B 0x0067
Teclado/Teclado Teclado F17 0x0007 0x006C 0x0068
Teclado/Teclado Teclado F18 0x0007 0x006D 0x0069
Teclado/Teclado Teclado F19 0x0007 0x006E 0x006A
Teclado/Teclado Teclado F20 0x0007 0x006F 0x006B
Teclado/Teclado Teclado F21 0x0007 0x0070 0x006C
Teclado/Teclado Teclado F22 0x0007 0x0071 0x006D
Teclado/Teclado Teclado F23 0x0007 0x0072 0x006E
Teclado/Teclado Teclado F24 0x0007 0x0073 0x0076
Teclado/Teclado Vírgula do teclado 0x0007 0x0085 0x007E 107 *Nota 4
Teclado/Teclado Teclado Internacional1 0x0007 0x0087 0x0073 56 *Nota 4, 5
Teclado/Teclado Teclado Internacional2 0x0007 0x0088 0x0070 133 *Nota 5
Teclado/Teclado Teclado Internacional3 0x0007 0x0089 0x007D 14 *Nota 5
Teclado/Teclado Teclado Internacional4 0x0007 0x008A 0x0079 132 *Nota 5
Teclado/Teclado Teclado Internacional5 0x0007 0x008B 0x007B 131 *Nota 5
Teclado/Teclado Teclado Internacional6 0x0007 0x008C 0x005C
Teclado/Teclado Teclado LANG1 0x0007 0x0090 0x0072 *Nota 6
0x00F2 *Nota 3, 6
Teclado/Teclado Teclado LANG2 0x0007 0x0091 0x0071 *Nota 6
0x00F1 *Nota 3, 6
Teclado/Teclado Teclado LANG3 0x0007 0x0092 0x0078
Teclado/Teclado Teclado LANG4 0x0007 0x0093 0x0077
Teclado/Teclado Teclado LANG5 0x0007 0x0094 0x0076
Teclado/Teclado Teclado LeftControl 0x0007 0x00E0 0x001D 58
Teclado/Teclado Teclado LeftShift 0x0007 0x00E1 0x002A 44
Teclado/Teclado Teclado LeftAlt 0x0007 0x00E2 0x0038 60
Teclado/Teclado GUI esquerda do teclado 0x0007 0x00E3 0xE05B 127
Teclado/Teclado RightControl do teclado 0x0007 0x00E4 0xE01D 64
Teclado/Teclado RightShift do teclado 0x0007 0x00E5 0x0036 57
Teclado/Teclado RightAlt do teclado 0x0007 0x00E6 0xE038 62
Teclado/Teclado GUI direita do teclado 0x0007 0x00E7 0xE05C 128
Consumidor Verificar próxima faixa 0x000C 0x00B5 0xE019
Consumidor Verificar faixa anterior 0x000C 0x00B6 0xE010
Consumidor Parar 0x000C 0x00B7 0xE024
Consumidor Reproduzir/Pausar 0x000C 0x00CD 0xE022
Consumidor Ativar Mudo 0x000C 0x00E2 0xE020
Consumidor Incremento de volume 0x000C 0x00E9 0xE030
Consumidor Decremento de Volume 0x000C 0x00EA 0xE02E
Consumidor Configuração de Controle do Consumidor AL 0x000C 0x0183 0xE06D
Consumidor Leitor de email AL 0x000C 0x018A 0xE06C
Consumidor Calculadora AL 0x000C 0x0192 0xE021
Consumidor Navegador de máquina local AL 0x000C 0x0194 0xE06B
Consumidor Pesquisa AC 0x000C 0x0221 0xE065
Consumidor Início AC 0x000C 0x0223 0xE032
Consumidor Voltar AC 0x000C 0x0224 0xE06A
Consumidor Avançar AC 0x000C 0x0225 0xE069
Consumidor Interromper AC 0x000C 0x0226 0xE068
Consumidor Atualizar AC 0x000C 0x0227 0xE067
Consumidor Indicadores de CA 0x000C 0x022A 0xE066

Observações:

  1. O código de verificação de teclas SysRq é emitido no pressionamento de tecla Alt+PrintScreen
  2. A interrupção do código de verificação de tecla é emitido no pressionamento de tecla Control+Pause
  3. Como visto em mensagens de teclado herdadas
  4. A tecla está presente nos teclados brasileiros
  5. A tecla está presente nos teclados japoneses
  6. O código de verificação é emitido somente no evento de liberação de chave

Sinalizador de tecla estendida

O sinalizador de tecla estendida indica se a mensagem de pressionamento de tecla se originou de uma das teclas adicionais do Teclado avançado de 101/102 teclas. As teclas estendidas consistem nas teclas ALT e CTRL no lado direito do teclado; as teclas INS, DEL, HOME, END, PAGE UP, PAGE DOWN e as setas de direção nos conjuntos à esquerda do teclado numérico; a tecla NUM LOCK; a tecla BREAK (CTRL+PAUSE) ; a tecla PRINT SCRN; e as teclas de divisão (/) e ENTER no teclado numérico. A tecla SHIFT à direita não é considerada uma tecla estendida. Ela tem um código de verificação separado.

Se especificado, o código de verificação consistirá em uma sequência de dois bytes, sendo que o primeiro byte tem um valor igual a 0xE0.

Código de contexto

O código de contexto indica se a tecla ALT estava inativa quando a mensagem de pressionamento de tecla foi gerada. O código é 1 se a tecla ALT estava inativa e 0 se ela estava ativa.

Sinalizador de estado anterior da tecla

O sinalizador de estado anterior da tecla indica se a tecla que gerou a mensagem de pressionamento de tecla estava liberada ou pressionada. É 1 se a tecla estava pressionada e 0 se a tecla estava liberada. Use esse sinalizador para identificar as mensagens de pressionamento de tecla geradas pelo recurso de repetição automática do teclado. Esse sinalizador é definido como 1 para mensagens de pressionamento de tecla WM_KEYDOWN e WM_SYSKEYDOWN geradas pelo recurso de repetição automática. Ele é sempre definido como 1 para mensagens WM_KEYUP e WM_SYSKEYUP.

Sinalizador de estado de transição

O sinalizador de estado de transição indica se o pressionamento ou a liberação de uma tecla gerou a mensagem de pressionamento de tecla. Esse sinalizador é sempre definido como 0 para as mensagens WM_KEYDOWN e WM_SYSKEYDOWN e é sempre definido como 1 para as mensagens WM_KEYUP e WM_SYSKEYUP.

Mensagens de caractere

As mensagens de pressionamento de tecla fornecem muitas informações sobre os pressionamentos de tecla, mas não fornecem códigos de caractere para pressionamentos de tecla de caractere. Para recuperar códigos de caractere, um aplicativo precisa incluir a função TranslateMessage no loop de mensagens do thread. TranslateMessage transmite uma mensagem WM_KEYDOWN ou WM_SYSKEYDOWN para o layout de teclado. O layout examina o código de tecla virtual da mensagem e, se ele corresponder a uma tecla de caractere, fornecerá o código de caractere equivalente (levando em conta o estado das teclas SHIFT e CAPS LOCK). Em seguida, ele gera uma mensagem de caractere que inclui o código de caractere e coloca a mensagem na parte superior da fila de mensagens. A próxima iteração do loop de mensagens remove a mensagem de caractere da fila e a envia para o procedimento de janela apropriado.

Esta seção contém os seguintes tópicos:

Mensagens de caracteres que não são do sistema

Um procedimento de janela pode receber as seguintes mensagens de caracteres: WM_CHAR, WM_DEADCHAR, WM_SYSCHAR, WM_SYSDEADCHAR e WM_UNICHAR. A função TranslateMessage gera uma mensagem WM_CHAR ou WM_DEADCHAR quando processa uma mensagem WM_KEYDOWN. Da mesma forma, ela gera uma mensagem WM_SYSCHAR ou WM_SYSDEADCHAR quando processa uma mensagem WM_SYSKEYDOWN.

Um aplicativo que processa a entrada de teclado normalmente ignora todas as mensagens, exceto WM_CHAR e WM_UNICHAR, transmitindo qualquer outra mensagem para a função DefWindowProc. Observe que WM_CHAR usa o UTF-16 (Formato de Transformação Unicode de 16 bits) ou o conjunto de caracteres ANSI, enquanto WM_UNICHAR sempre usa o UTF-32 (Formato de Transformação Unicode de 32 bits). O sistema usa as mensagens WM_SYSCHAR e WM_SYSDEADCHAR para implementar mnemônicos de menu.

O parâmetro wParam de todas as mensagens de caracteres contém o código de caractere da tecla de caractere que foi pressionada. O valor do código de caractere depende da classe da janela que recebe a mensagem. Se a versão Unicode da função RegisterClass foi usada para registrar a classe de janela, o sistema fornece caracteres Unicode para todas as janelas dessa classe. Caso contrário, o sistema fornece códigos de caractere ANSI. Para obter mais informações, confira Como registrar classes de janela e Usar páginas de código UTF-8 em aplicativos do Windows.

O conteúdo do parâmetro lParam de uma mensagem de caractere é idêntico ao conteúdo do parâmetro lParam da mensagem de tecla pressionada que foi convertida para produzir a mensagem de caractere. Para obter informações, confira Sinalizadores de mensagem de pressionamento de tecla.

Mensagens de caracteres inativos

Alguns teclados que não são em inglês contêm teclas de caracteres que não devem produzir caracteres sozinhas. Em vez disso, elas são usadas para adicionar um diacrítico ao caractere produzido pelo pressionamento de tecla seguinte. Essas teclas são chamadas de teclas inativas. A tecla de circunflexo em um teclado alemão é um exemplo de uma tecla inativa. Para inserir o caractere que consiste em um "o" com um circunflexo, um usuário alemão digitará a tecla de circunflexo seguida da tecla "o". A janela com o foco do teclado receberá a seguinte sequência de mensagens:

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

TranslateMessage gera a mensagem WM_DEADCHAR quando processa a mensagem WM_KEYDOWN de uma tecla inativa. Embora o parâmetro wParam da mensagem WM_DEADCHAR contenha o código de caractere do diacrítico da tecla inativa, um aplicativo normalmente ignora a mensagem. Em vez disso, ele processa a mensagem WM_CHAR gerada pelo pressionamento de tecla seguinte. O parâmetro wParam da mensagem WM_CHAR contém o código de caractere da letra com o diacrítico. Se o pressionamento de tecla seguinte gerar um caractere que não pode ser combinado com um diacrítico, o sistema vai gerar duas mensagens WM_CHAR. O parâmetro wParam do primeiro contém o código de caractere do diacrítico. O parâmetro wParam do segundo contém o código de caractere da tecla de caractere seguinte.

A função TranslateMessage gera a mensagem WM_SYSDEADCHAR quando processa a mensagem WM_SYSKEYDOWN por meio de uma tecla inativa do sistema (uma tecla inativa que é pressionada em combinação com a tecla ALT). Um aplicativo normalmente ignora a mensagem WM_SYSDEADCHAR.

Status da tecla

Ao processar uma mensagem de teclado, um aplicativo poderá precisar determinar o status de outra tecla além daquela que gerou a mensagem atual. Por exemplo, um aplicativo de processamento de palavras que permite que o usuário pressione SHIFT+END para selecionar um bloco de texto precisa verificar o status da tecla SHIFT sempre que receber uma mensagem de pressionamento de tecla da tecla END. O aplicativo pode usar a função GetKeyState para determinar o status de uma tecla virtual no momento em que a mensagem atual foi gerada. Ele pode usar a função GetAsyncKeyState para recuperar o status atual de uma tecla virtual.

O layout do teclado mantém uma lista de nomes. O nome de uma tecla que produz um caractere individual é o mesmo caractere produzido pela tecla. O nome de uma tecla que não é de caractere, como TAB e ENTER, é armazenado como uma cadeia de caracteres. Um aplicativo pode recuperar o nome de qualquer tecla do driver de dispositivo chamando a função GetKeyNameText.

Pressionamento de tecla e conversões de caracteres

O sistema inclui várias funções de finalidade especial que convertem códigos de verificação, códigos de caractere e códigos de tecla virtual fornecidos por várias mensagens de pressionamento de tecla. Essas funções incluem MapVirtualKey, ToAscii, ToUnicode e VkKeyScan.

Além disso, o Microsoft Rich Edit 3.0 dá suporte ao IME HexToUnicode, que permite que um usuário converta caracteres hexadecimais e Unicode usando teclas de acesso. Isso significa que, quando o Microsoft Rich Edit 3.0 for incorporado a um aplicativo, o aplicativo herdará os recursos do IME HexToUnicode.

Suporte às teclas de acesso

Uma tecla de acesso é uma combinação de teclas que gera uma mensagem WM_HOTKEY, uma mensagem que o sistema coloca na parte superior da fila de mensagens de um thread, ignorando todas as mensagens existentes na fila. Os aplicativos usam as teclas de acesso para obter a entrada de teclado de alta prioridade do usuário. Por exemplo, definindo uma tecla de acesso que consiste na combinação de teclas CTRL+C, um aplicativo pode permitir que o usuário cancele uma operação longa.

Para definir uma tecla de acesso, um aplicativo chama a função RegisterHotKey, especificando a combinação de teclas que gera a mensagem WM_HOTKEY, o identificador para a janela a fim de receber a mensagem e o identificador da tecla de acesso. Quando o usuário pressiona a tecla de acesso, uma mensagem WM_HOTKEY é colocada na fila de mensagens do thread que criou a janela. O parâmetro wParam da mensagem contém o identificador da tecla de acesso. O aplicativo pode definir várias teclas de acesso para um thread, mas cada tecla de acesso no thread precisa ter um identificador exclusivo. Antes que o aplicativo seja encerrado, ele deve usar a função UnregisterHotKey para destruir a tecla de acesso.

Os aplicativos podem usar um controle de tecla de acesso para facilitar a escolha de uma tecla de acesso pelo usuário. Os controles de tecla de acesso são normalmente usados para definir uma tecla de acesso que ativa uma janela. Eles não usam as funções RegisterHotKey e UnregisterHotKey. Em vez disso, um aplicativo que usa um controle de tecla de acesso normalmente envia a mensagem WM_SETHOTKEY para definir a tecla de acesso. Sempre que o usuário pressiona a tecla de atalho, o sistema envia uma mensagem WM_SYSCOMMAND especificando a SC_HOTKEY. Para obter mais informações sobre os controles de tecla de acesso, confira "Como usar controles de tecla de acesso" em Controles de teclas de acesso.

Teclas de teclado para navegação e outras funções

O Windows dá suporte a teclados com teclas especiais para funções de navegador, funções de mídia, inicialização de aplicativos e gerenciamento de energia. O WM_APPCOMMAND dá suporte às teclas de teclado extras. Além disso, a função ShellProc é modificada para dar suporte às teclas de teclado extras.

É improvável que uma janela filho em um aplicativo de componente possa implementar comandos diretamente para essas teclas de teclado extras. Portanto, quando uma dessas teclas for pressionada, DefWindowProc enviará uma mensagem WM_APPCOMMAND para uma janela. DefWindowProc também propagará a mensagem WM_APPCOMMAND para a janela pai. Isso é semelhante à maneira como os menus de contexto são invocados com o botão direito do mouse, que é quando o DefWindowProc envia uma mensagem WM_CONTEXTMENU em um clique de botão direito e a propaga para o pai. Além disso, se DefWindowProc receber uma mensagem WM_APPCOMMAND para uma janela de nível superior, ele chamará um gancho de shell com o código HSHELL_APPCOMMAND.

O Windows também dá suporte ao Microsoft IntelliMouse Explorer, que é um mouse com cinco botões. Os dois botões extras dão suporte à navegação progressiva e regressiva do navegador. Para obter mais informações, confira XBUTTONs.

Como simular uma entrada

Para simular uma série ininterrupta de eventos de entrada do usuário, use a função SendInput. A função aceita três parâmetros. O primeiro parâmetro, cInputs, indica o número de eventos de entrada que serão simulados. O segundo parâmetro, rgInputs, é uma matriz de estruturas INPUT, cada uma descrevendo um tipo de evento de entrada e informações adicionais sobre esse evento. O último parâmetro, cbSize, aceita o tamanho da estrutura INPUT, em bytes.

A função SendInput funciona com a injeção de uma série de eventos de entrada simulados no fluxo de entrada de um dispositivo. O efeito é semelhante a chamar a função keybd_event ou mouse_event repetidamente, com a exceção de que o sistema garante que nenhum outro evento de entrada interaja com os eventos simulados. Quando a chamada for concluída, o valor retornado indicará o número de eventos de entrada reproduzidos com sucesso. Se esse valor é zero, a entrada foi bloqueada.

A função SendInput não redefine o estado atual do teclado. Portanto, se o usuário tiver alguma tecla pressionada quando você chamar essa função, ela poderá interferir nos eventos gerados pela função. Se você estiver preocupado com possíveis interferências, verifique o estado do teclado com a função GetAsyncKeyState e corrija-o conforme necessário.

Idiomas, localidades e layouts de teclado

Um idioma é um idioma natural, como inglês, francês e japonês. Um subidioma é uma variante de um idioma natural que é falado em uma região geográfica específica, como os subidiomas do inglês falados no Reino Unido e nos Estados Unidos. Os aplicativos usam valores, chamados identificadores de idioma, para identificar exclusivamente idiomas e subidiomas.

Normalmente, os aplicativos usam localidades para definir o idioma no qual a entrada e a saída são processadas. A definição da localidade do teclado, por exemplo, afeta os valores de caractere gerados pelo teclado. A definição da localidade do monitor ou da impressora afeta os glifos exibidos ou impressos. Os aplicativos definem a localidade de um teclado carregando e usando layouts de teclado. Eles definem a localidade de um monitor ou de uma impressora selecionando uma fonte que dê suporte à localidade especificada.

Um layout de teclado especifica a posição física das teclas no teclado e determina os valores de caractere gerados pelo pressionamento dessas teclas. Cada layout identifica o idioma de entrada atual e determina quais valores de caractere são gerados por quais teclas e combinações de teclas.

Cada layout de teclado tem um identificador correspondente que identifica o layout e o idioma. A palavra inferior do identificador é um identificador de idioma. A palavra superior é um identificador de dispositivo, especificando o layout físico, ou é zero, indicando um layout físico padrão. O usuário pode associar qualquer idioma de entrada a um layout físico. Por exemplo, um usuário de língua inglesa que trabalha ocasionalmente em francês pode definir o idioma de entrada do teclado como francês sem alterar o layout físico do teclado. Isso significa que o usuário pode inserir um texto em francês usando o layout em inglês já conhecido.

Em geral, não é esperado que os aplicativos processem os idiomas de entrada diretamente. Em vez disso, o usuário configura as combinações de idioma e layout e alterna entre elas. Quando o usuário clica no texto marcado com um idioma diferente, o aplicativo chama a função ActivateKeyboardLayout para ativar o layout padrão do usuário para esse idioma. Se o usuário editar um texto em um idioma que não esteja na lista ativa, o aplicativo poderá chamar a função LoadKeyboardLayout com o idioma para obter um layout com base nesse idioma.

A função ActivateKeyboardLayout define o idioma de entrada para a tarefa atual. O parâmetro hkl pode ser o identificador para o layout do teclado ou um identificador de idioma estendido com zero. Os identificadores de layout de teclado podem ser obtidos por meio da função LoadKeyboardLayout ou GetKeyboardLayoutList. Os valores HKL_NEXT e HKL_PREV também podem ser usados para selecionar o teclado próximo ou anterior.

A função GetKeyboardLayoutName recupera o nome do layout do teclado ativo para o thread de chamada. Se um aplicativo criar o layout ativo usando a função LoadKeyboardLayout, GetKeyboardLayoutName vai recuperar a mesma cadeia de caracteres usada para criar o layout. Caso contrário, a cadeia de caracteres será o identificador de idioma primário correspondente à localidade do layout ativo. Isso significa que a função talvez não necessariamente diferencie layouts distintos com o mesmo idioma primário, ou seja, não pode retornar informações específicas sobre o idioma de entrada. No entanto, a função GetKeyboardLayout pode ser usada para determinar o idioma de entrada.

A função LoadKeyboardLayout carrega um layout de teclado e disponibiliza o layout para o usuário. Os aplicativos podem tornar o layout imediatamente ativo para o thread atual usando o valor KLF_ACTIVATE. Um aplicativo pode usar o valor KLF_REORDER para reordenar os layouts sem especificar também o valor KLF_ACTIVATE. Os aplicativos sempre devem usar o valor KLF_SUBSTITUTE_OK ao carregar layouts de teclado para garantir que a preferência do usuário, se houver, esteja selecionada.

Para suporte multilíngue, a função LoadKeyboardLayout fornece os sinalizadores KLF_REPLACELANG e KLF_NOTELLSHELL. O sinalizador KLF_REPLACELANG instrui a função a substituir um layout de teclado existente sem alterar o idioma. A tentativa de substituir um layout existente usando o mesmo identificador de idioma, mas sem especificar KLF_REPLACELANG é um erro. O sinalizador KLF_NOTELLSHELL impede que a função notifique o shell quando um layout de teclado é adicionado ou substituído. Isso é útil para aplicativos que adicionam vários layouts em uma série consecutiva de chamadas. Esse sinalizador deve ser usado em todas, exceto na última chamada.

A função UnloadKeyboardLayout é restrita porque não pode descarregar o idioma de entrada padrão do sistema. Isso garante que o usuário sempre tenha um layout disponível para inserir o texto usando o mesmo conjunto de caracteres usado pelo shell e pelo sistema de arquivos.