Share via


Entrée de clavier (Bien démarrer avec Win32 et C++)

Le clavier est utilisé pour plusieurs types d’entrée distincts, notamment :

  • Entrée de caractère. Texte que l’utilisateur tape dans un document ou une zone d’édition.
  • Raccourcis clavier. Traits de clé qui appellent des fonctions d’application ; par exemple, CTRL + O pour ouvrir un fichier.
  • Commandes système. Traits clés qui appellent des fonctions système ; par exemple, ALT + TAB pour changer de fenêtre.

Lorsque vous pensez à l’entrée au clavier, il est important de se rappeler qu’un trait de touche n’est pas identique à un caractère. Par exemple, l’appui sur la touche A peut entraîner l’un des caractères suivants.

  • a
  • A
  • á (si le clavier prend en charge la combinaison de diacritiques)

En outre, si la touche ALT est maintenue enfoncée, l’appui sur la touche A génère ALT+A, ce que le système ne traite pas du tout comme un caractère, mais plutôt comme une commande système.

Codes clés

Lorsque vous appuyez sur une touche, le matériel génère un code d’analyse. Les codes d’analyse varient d’un clavier à l’autre, et il existe des codes d’analyse distincts pour les événements key-up et key-down. Vous ne vous soucierez presque jamais des codes d’analyse. Le pilote de clavier traduit les codes d’analyse en codes de touche virtuelle. Les codes de clé virtuelle sont indépendants de l’appareil. Le fait d’appuyer sur la touche A de n’importe quel clavier génère le même code de touche virtuelle.

En général, les codes de clé virtuelle ne correspondent pas aux codes ASCII ou à toute autre norme d’encodage de caractères. Cela est évident si vous y réfléchissez, car la même clé peut générer des caractères différents (a, A, á), et certaines clés, telles que les touches de fonction, ne correspondent à aucun caractère.

Cela dit, les codes de clé virtuelle suivants sont mappés à des équivalents ASCII :

  • 0 à 9 clés = ASCII '0' – '9' (0x30 - 0x39)
  • Clés A à Z = ASCII 'A' – 'Z' (0x41 - 0x5A)

À certains égards, ce mappage est regrettable, car vous ne devez jamais considérer les codes de clé virtuelle comme des caractères, pour les raisons décrites.

Le fichier d’en-tête WinUser.h définit des constantes pour la plupart des codes de clé virtuelle. Par exemple, le code de clé virtuelle de la touche FLÈCHE GAUCHE est VK_LEFT (0x25). Pour obtenir la liste complète des codes de clé virtuelle, consultez Codes de clé virtuelle. Aucune constante n’est définie pour les codes de clé virtuelle qui correspondent aux valeurs ASCII. Par exemple, le code de clé virtuelle de la clé A est 0x41, mais il n’existe aucune constante nommée VK_A. Au lieu de cela, utilisez simplement la valeur numérique.

messages Key-Down et Key-Up

Lorsque vous appuyez sur une touche, la fenêtre qui a le focus clavier reçoit l’un des messages suivants.

Le message WM_SYSKEYDOWN indique une clé système, qui est un trait de clé qui appelle une commande système. Il existe deux types de clé système :

  • ALT + n’importe quelle touche
  • F10

La touche F10 active la barre de menus d’une fenêtre. Différentes combinaisons de touches ALT appellent des commandes système. Par exemple, ALT + TAB bascule vers une nouvelle fenêtre. En outre, si une fenêtre a un menu, la touche ALT peut être utilisée pour activer les éléments de menu. Certaines combinaisons de touches ALT ne font rien.

Tous les autres traits de clé sont considérés comme des clés non système et produisent le message WM_KEYDOWN . Cela inclut les clés de fonction autres que F10.

Lorsque vous relâchez une clé, le système envoie un message de clé haute correspondant :

Si vous maintenez une touche enfoncée suffisamment longtemps pour démarrer la fonctionnalité de répétition du clavier, le système envoie plusieurs messages de touche vers le bas, suivis d’un seul message de touche haut.

Dans les quatre messages clavier abordés jusqu’à présent, le paramètre wParam contient le code de clé virtuelle de la touche. Le paramètre lParam contient des informations diverses emballées en 32 bits. Vous n’avez généralement pas besoin des informations dans lParam. Un indicateur qui peut être utile est le bit 30, l’indicateur « état de la clé précédente », qui est défini sur 1 pour les messages de touche descendant répétés.

Comme leur nom l’indique, les traits de clé système sont principalement destinés au système d’exploitation. Si vous interceptez le message WM_SYSKEYDOWN , appelez Ensuite DefWindowProc . Sinon, vous empêcherez le système d’exploitation de gérer la commande.

Messages de caractères

Les traits de clé sont convertis en caractères par la fonction TranslateMessage , que nous avons vue pour la première fois dans le module 1. Cette fonction examine les messages key-down et les traduit en caractères. Pour chaque caractère produit, la fonction TranslateMessage place un message WM_CHAR ou WM_SYSCHAR dans la file d’attente des messages de la fenêtre. Le paramètre wParam du message contient le caractère UTF-16.

Comme vous pouvez le deviner, WM_CHAR messages sont générés à partir de WM_KEYDOWN messages, tandis que les messages WM_SYSCHAR sont générés à partir de WM_SYSKEYDOWN messages. Par exemple, supposons que l’utilisateur appuie sur la touche MAJ suivie de la touche A. En supposant une disposition de clavier standard, vous obtiendrez la séquence de messages suivante :

WM_KEYDOWN : MAJ
WM_KEYDOWN : A
WM_CHAR : « A »

D’autre part, la combinaison ALT + P générerait :

WM_SYSKEYDOWN : VK_MENU
WM_SYSKEYDOWN : 0x50
WM_SYSCHAR : 'p'
WM_SYSKEYUP : 0x50
WM_KEYUP : VK_MENU

(Le code de clé virtuelle de la clé ALT est nommé VK_MENU pour des raisons historiques.)

Le message WM_SYSCHAR indique un caractère système. Comme avec WM_SYSKEYDOWN, vous devez généralement passer ce message directement à DefWindowProc. Sinon, vous risquez d’interférer avec les commandes système standard. En particulier, ne traitez pas WM_SYSCHAR comme du texte que l’utilisateur a tapé.

Le message WM_CHAR correspond à ce que vous considérez normalement comme une entrée de caractère. Le type de données du caractère est wchar_t, représentant un caractère Unicode UTF-16. L’entrée de caractères peut inclure des caractères en dehors de la plage ASCII, en particulier avec les dispositions de clavier couramment utilisées en dehors du États-Unis. Vous pouvez essayer différentes dispositions de clavier en installant un clavier régional, puis en utilisant la fonctionnalité Clavier à l’écran.

Les utilisateurs peuvent également installer un éditeur de méthode d’entrée (IME) pour entrer des scripts complexes, tels que des caractères japonais, avec un clavier standard. Par exemple, en utilisant un IME japonais pour entrer le caractère katakana カ (ka), vous pouvez obtenir les messages suivants :

WM_KEYDOWN : VK_PROCESSKEY (clé processus IME)
WM_KEYUP : 0x4B
WM_KEYDOWN : VK_PROCESSKEY
WM_KEYUP : 0x41
WM_KEYDOWN : VK_PROCESSKEY
WM_CHAR : カ
WM_KEYUP : VK_RETURN

Certaines combinaisons de touches CTRL sont traduites en caractères de contrôle ASCII. Par exemple, CTRL+A est traduit en caractère CTRL-A (SOH) ASCII (valeur ASCII 0x01). Pour la saisie de texte, vous devez généralement filtrer les caractères de contrôle. Évitez également d’utiliser WM_CHAR pour implémenter des raccourcis clavier. Utilisez plutôt WM_KEYDOWN messages ; ou encore mieux, utilisez une table d’accélérateur. Les tables accélérateurs sont décrites dans la rubrique suivante, Tables accélérateurs.

Le code suivant affiche les messages de clavier main dans le débogueur. Essayez de jouer avec différentes combinaisons de touches et voyez quels messages sont générés.

Notes

Veillez à inclure wchar.h, sinon swprintf_s ne sera pas défini.

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    wchar_t msg[32];
    switch (uMsg)
    {
    case WM_SYSKEYDOWN:
        swprintf_s(msg, L"WM_SYSKEYDOWN: 0x%x\n", wParam);
        OutputDebugString(msg);
        break;

    case WM_SYSCHAR:
        swprintf_s(msg, L"WM_SYSCHAR: %c\n", (wchar_t)wParam);
        OutputDebugString(msg);
        break;

    case WM_SYSKEYUP:
        swprintf_s(msg, L"WM_SYSKEYUP: 0x%x\n", wParam);
        OutputDebugString(msg);
        break;

    case WM_KEYDOWN:
        swprintf_s(msg, L"WM_KEYDOWN: 0x%x\n", wParam);
        OutputDebugString(msg);
        break;

    case WM_KEYUP:
        swprintf_s(msg, L"WM_KEYUP: 0x%x\n", wParam);
        OutputDebugString(msg);
        break;

    case WM_CHAR:
        swprintf_s(msg, L"WM_CHAR: %c\n", (wchar_t)wParam);
        OutputDebugString(msg);
        break;

    /* Handle other messages (not shown) */

    }
    return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
}

Messages clavier divers

Certains autres messages clavier peuvent être ignorés en toute sécurité par la plupart des applications.

  • Le message WM_DEADCHAR est envoyé pour une clé de combinaison, telle qu’une touche diacritique. Par exemple, sur un clavier de langue espagnole, la saisie d’accentuation (') suivie de E produit le caractère é. Le WM_DEADCHAR est envoyé pour le caractère d’accentuation.
  • Le message WM_UNICHAR est obsolète. Il permet aux programmes ANSI de recevoir des entrées de caractères Unicode.
  • Le caractère WM_IME_CHAR est envoyé lorsqu’un IME traduit une séquence de frappe en caractères. Il est envoyé en plus du message WM_CHAR habituel.

État du clavier

Les messages du clavier sont pilotés par les événements. Autrement dit, vous recevez un message quand quelque chose d’intéressant se produit, comme un appui sur la touche, et que le message vous indique ce qui vient de se passer. Mais vous pouvez également tester l’état d’une clé à tout moment, en appelant la fonction GetKeyState .

Par exemple, réfléchissez à la façon de détecter la combinaison de clic gauche de la souris + touche ALT. Vous pouvez suivre l’état de la clé ALT en écoutant les messages de trait de touche et en stockant un indicateur, mais GetKeyState vous évite les problèmes. Lorsque vous recevez le message WM_LBUTTONDOWN , il vous suffit d’appeler GetKeyState comme suit :

if (GetKeyState(VK_MENU) & 0x8000)
{
    // ALT key is down.
}

Le message GetKeyState prend un code de clé virtuelle comme entrée et retourne un ensemble d’indicateurs de bits (en fait, seulement deux indicateurs). La valeur 0x8000 contient l’indicateur de bits qui teste si la touche est actuellement enfoncée.

La plupart des claviers ont deux touches ALT, gauche et droite. L’exemple précédent teste si l’un d’eux a appuyé. Vous pouvez également utiliser GetKeyState pour faire la distinction entre les instances gauche et droite des touches Alt, Maj ou Ctrl. Par exemple, le code suivant teste si la touche ALT droite est enfoncée.

if (GetKeyState(VK_RMENU) & 0x8000)
{
    // Right ALT key is down.
}

La fonction GetKeyState est intéressante, car elle signale un état de clavier virtuel . Cet état virtuel est basé sur le contenu de votre file d’attente de messages et est mis à jour lorsque vous supprimez des messages de la file d’attente. Lorsque votre programme traite les messages de fenêtre, GetKeyState vous donne une instantané du clavier au moment où chaque message a été mis en file d’attente. Par exemple, si le dernier message de la file d’attente était WM_LBUTTONDOWN, GetKeyState signale l’état du clavier au moment où l’utilisateur a cliqué sur le bouton de la souris.

Étant donné que GetKeyState est basé sur votre file d’attente de messages, il ignore également l’entrée au clavier qui a été envoyée à un autre programme. Si l’utilisateur bascule vers un autre programme, toutes les touches qui sont envoyées à ce programme sont ignorées par GetKeyState. Si vous voulez vraiment connaître l’état physique immédiat du clavier, il existe une fonction pour cela : GetAsyncKeyState. Toutefois, pour la plupart du code de l’interface utilisateur, la fonction correcte est GetKeyState.

Suivant

Tables accélérateurs