Les messages d'évènements de touche
Le système va envoyer le message WM_KEYDOWN
ou WM_SYSKEYDOWN lorsque l'utilisateur
appuie sur une touche. Il va envoyer le message WM_KEYUP
ou WM_SYSKEYUP lorsque l'utilisateur
relache une touche. Comme seule la fenêtre ayant le focus
peut recevoir des messages concernant le clavier,
il est tout à fait possible que la procédure
de la fenêtre ne reçoive que WM_KEYDOWN
ou WM_SYSKEYDOWN sans jamais
recevoir WM_KEYUP ou WM_SYSKEYUP
par suite de changement de focus ou inversement
Lors d'un appuie prolongé sur une touche, Windows va envoyer une série
de WM_KEYDOWN ou WM_SYSKEYDOWN, mais un seul message WM_KEYUP ou WM_SYSKEYUP
lorsque l'utilisateur relâche la touche.
Comme tous les
messages, ces messages sont datés. Vous pouvez donc connaître la
durée entre le moment où l'utilisateur a appuyé sur la
touche et le moment où il l'a relâché grâce la fonction
GetMessageTime().
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
… |
16 |
15 |
… |
00 |
Etat transitoire |
Etat antérieur |
Code de contexte |
Drapeau de touche étendue |
Code de balayage OEM 8 bits |
Compteur de répétition 16 bits |
Le compteur de répétition :
Si votre procédure de fenêtre
n'est pas assez rapide pour traiter la répétitions d'une touche,
Windows va combiner les messages pour
n'en faire qu'un seul et incrémenter ce compteur
Pour traiter ce compteur, rien de plus simple puisqu'il s'agit de la partie basse d'un long. Vous utiliserez une syntaxe du type compteur = LOWORD(lParam);
On évite
en général de traiter le compteur de répétition
sur certaines touches particulières: Par exemple si vous utilisez la
touche F3 pour sauvegarder, inutile de relancer n fois la sauvegarde. une fois
suffit ! Par contre, s'il s'agit de traiter le compteur du message WM_CHAR (Voir
chapitre suivant Message caractères), alors
là pas de problème !
Code balayage OEM :
C'est le code clavier (le même que celui que l'on peut récupérer
via l'interruption 16H sous DOS). A éviter, car il existe plusieurs pays,
et donc différentes affectations possibles pour une touche
Préférez le code de touches virtuelles !
Drapeau de touche étendue :
A 1 s'il s'agit d'une touche spécifique aux claviers étendus
On
peut normalement l'ignorer !
Code contexte :
Ce bit est à 1 pour les messages WM_SYSKEYDOWN ou WM_SYSKEYUP. A 0 pour
WM_KEYDOWN ou WM_KEYUP sauf :
- Si la fenêtre est sous forme d'icône. Dans ce cas, tous les évènements
vont produire WM_SYSKEYDOWN ou WM_SYSKEYUP. Cependant, si la touche ALT n'est
pas pressée, le code contexte sera à 0.
- Certaines combinaisons de touches avec Shift, Alt ou Ctrl de certain clavier
avec une touche, alors que cette touche n'est pas une touche système
produiera un code à 1.
Etat transitoire :
A 0 si la touche vient d'être enfoncée, à 1 si relâchée.
wParam ou le code de touches virtuelles:
Ce paramètre va recevoir le code virtuelle de la touche préssée. C'est évidemment ce code qu'il sera préférable d'utiliser, car contrairement au code OEM, il est portable sur tout type de clavier. Ces codes commencent par VK_. Pour avoir une liste exaustive voir ici la liste des codes de touches virtuelles.
L'ennui, c'est que pour la touche correspondant à la lettre A, vous ne pourrez pas savoir si les touches SHIFT, CTRL ou ALT sont aussi pressées !
Il y a une première solution, mais évidemment ce n'est pas la meilleur, car il en existe une autre !
En complément avec ces messages, Windows met à votre disposition la fonction GetKeyState():
SHORT GetKeyState(
int nVirtKey
);
Où nVirtKey est le code virtuelle de la touche.
En sortie, le bit de poid fort à 1 indique que la touche est pressée,
à 0 sinon. Le bit de poid faible indique l'état des touches particulières
(comme Tab, Caps-Lock), à 1, la fonction correspondante est activée.
à 0 elle ne l'est pas. Ceci vous permettra de connaître dans le
même temps l'etat de la led correspondante !
SHORT équivaut
à définir votre variable de type octet signé. par conséquent,
si vous testez la valeur, celle-ci sera négative lorsque la touche testée
est pressée (Bit de poid fort oblige !)
Vous pourrez utiliser le code virtuel VK_SHIFT, VK_CONTROL et VK_MENU pour connaître l'état des différents boutons. Windows indiquera ainsi que Shift, Control ou ALT sont préssées ou non que ce soit le bouton de gauche ou de droite.
Pour différencier les boutons de droite ou de gauche, il faudra utiliser:
VK_LSHIFT, VK_RSHIFT, VK_LCONTROL, VK_RCONTROL, VK_LMENU ou VK_RMENU.
Cette fonction
retourne l'etat des boutons concernant uniquement le message en cours de traitement.
Donc l'état des boutons lorsque le message a été généré.
Cette valeur ne changera donc pas durant toute la période de traitement
du message.
Pour pouvoir lire à tout moment l'état en temps réel du clavier, il faut utiliser la fonction GetAsyncKeyState()...
Seulement, cette solution n'est pas la meilleur:
Il ne faut pas utiliser GetKeyState() + la touche pressée pour en déduire le caractère correspondant à afficher. Il ne faudrait pas oublier que le programme peut tourner dans différents pays, et il est des plus insupportables que de voir apparaître un caractère qui n'a rien à voir avec celui qui est déssiné sur son clavier. (Vous en avez peut-être déjà fait l'expérience avec la plupart des émulateurs !).
D'où le chapitre suivant...les messages de caractères
qu'il est préférable d'utiliser.