
|
auteur :
Hdd34 | Les touches de direction font partie des touches dites étendues. Celles-ci, en plus de renvoyer un code ASCII comme les autres, renvoient auparavant le code #0. Ainsi, pour savoir si une touche de direction a été pressée, il suffit de vérifer avec ReadKey, de l'unité Crt, si on obtient le code #0, et le cas échéant faire un second appel à ReadKey pour connaître le deuxième code de la touche.
Les touches étendues accesibles avec ReadKey sont :
- Les touches de fonction F1 à F10
- Les touches de déplacement (Origine, fin, page haut, page bas, haut, bas, gauche, droite)
- Les touches Suppr et Inser
Le tableau suivant recense les codes associés à ces touches étendues :
Touche
|
Codes ASCII
|
F1 à F10 |
#0, #59 à #68 |
Inser |
#0, #82 |
Suppr |
#0, #83 |
Origine |
#0, #71 |
Fin |
#0, #79 |
Page haut |
#0, #73 |
Page bas |
#0, #81 |
Haut |
#0, #72 |
Bas |
#0, #80 |
Gauche |
#0, #75 |
Droite |
#0, #77 |
L'exemple suivant teste l'appui sur les touches de direction et affiche le résultat à l'écran. On quitte le programme en appuyant sur Echap :
program ExFleches;
uses
Crt;
var
Ch: Char;
begin
repeat
Ch := ReadKey;
case Ch of
#0: case ReadKey of
#72: WriteLn('Haut');
#80: WriteLn('Bas');
#75: WriteLn('Gauche');
#77: WriteLn('Droite');
end;
end;
until Ch = #27;
end.
Remarques :
- Il existe d'autres touches étendues, mais non accessibles avec ReadKey : les touches de contrôle (Ctrl, Alt, Maj) ou bien les touches système (Impr Ecran, Arrêt Défil, Pause). Pour celles-ci, il faut utiliser une autre méthode. Reportez-vous à la question correspondante.
- On peut remarquer que les touches F11 et F12 sont à part. Cela vient du fait qu'elles sont apparues sur les claviers bien après les autres. Pour les détecter, il est nécessaire de reprogrammer l'interruption clavier $9.
|
lien : Comment détecter les touches de contrôle ?
|
|
auteur :
Hdd34 | Les touches de contrôle : Ctrl, Alt, Alt Gr ou Maj possède une place à part sur notre clavier. Leur manière de détection - mis à part au niveau de l'interruption clavier - est totalement différente de celle des autres touches.
On peut compter également dans les rangs des touches de contrôle les touches à bascule : Verr Num, Verr Maj, Inser ou Arrêt Défil.
Pour savoir si une de ces touches est actuellement pressée (active) ou relachée (inactive), il faut regarder la valeur du Word à l'adresse mémoire $0040:$0017. Chaque bit de ce mot est attribué à une touche. Si elle est pressée (ou active), le bit est à 1, sinon, il est à 0. Il est à noter que si les touches de contrôle sont en double (une gauche et une droite), alors elles sont gérées séparément. Le tableau suivant les décrit :
Touche
|
Bit(s) attribué(s)
|
Masque
|
Ctrl gauche |
2 et 8 |
$0104 |
Ctrl droite |
2 |
$0004 |
Maj gauche |
1 |
$0002 |
Maj droite |
0 |
$0001 |
Alt |
3 et 9 |
$0208 |
Alt Gr |
3 |
$0008 |
Verr Num |
5 |
$20 |
Verr Maj |
6 |
$40 |
Inser |
7 |
$80 |
Arrêt Défil |
4 |
$10 |
Pour connaître l'état du Word en $0040:$0017, on peut au choix utiliser le tableau MemW, ou bien, de manière plus pratique, se servir d'une variable Word déclarée en absolute, comme dans l'exemple ci-dessous.
Attention ! Les touches à bascule n'utilisent que le Byte à l'adresse $0040:$0017.
L'exemple suivant se charge de vérifier la combinaison de touches AltGr + E. Si ces deux touches sont pressées, alors le mot 'Euro' est affiché à l'écran. Attention ! La combinaison Alt+E correspond à une touche étendue. Mais tel quel, avec seulement ReadKey, il est impossible de savoir s'il s'agit juste de Alt ou bien AltGr. C'est ici qu'intervient notre code. On va distinguer Alt et AltGr. Si AltGr est pressé, alors seul le bit 3 est actif. Sinon, il y a aussi le bit 9. On va donc vérifier que le bit 3 est actif, mais pas le 9... Pour ce faire, on applique le masque isolant les bits 3 et 9, et on regarde si le bit 9 est bien éteint, alors que le 3 ne l'est pas.
program TestEuro;
uses
Crt;
var
KbdState: Word absolute $0040:$0017;
Ch: Char;
begin
repeat
Ch := ReadKey;
if Ch = #0 then
begin
if (ReadKey = #18) and (KbdState and $0208 = $0008) then
WriteLn('Euro');
end;
until Ch = #27;
end.
Remarque :
- Il est possible de modifier l'état d'une touche à bascule en modifiant directement en mémoire le bit souhaité. Attention toutefois, non seulement il ne faut modifier que le Byte à cet adresse, mais en plus, la modification du bit n'entraine pas un changement de couleur des LEDs du clavier ! Pour modifier aussi leur couleur en conséquence, il faudra utiliser le port $60 et lui envoyer la valeur $ED. Par exemple, pour activer l'état Num Lock, on écrira :
var
KbdSwitch: Byte absolute $0040:$0017;
OldSwitch: Word;
begin
OldSwitch := KbdSwitch;
KbdSwitch := OldSwitch and (not $20) or $20;
Port[$60] := $ED;
Port[$60] := (KbdSwitch shr 4) and 7;
OldSwitch := KbdSwitch;
KbdSwitch := OldSwitch and (not $20);
Port[$60] := $ED;
Port[$60] := (KbdSwitch shr 4) and 7;
end;
|
lien : Comment détecter l'appui sur les touches de direction ?
|
|
auteur :
Hdd34 | Certaines fois, lorsqu'un programme exécute une opération longue, l'utilisateur appuie sur les touches du clavier, alors que ces appuis ne devraient pas être pris en compte.
Cela devient très gênant si après l'opération le programme attend une réponse précise de la part de l'utilisateur.
On peut alors vider le tampon (le buffer) du clavier. Deux méthodes existent :
- Utiliser les procédures standards du Pascal
On se servira de l'unité Crt et de KeyPressed et ReadKey, comme ceci :
uses
Crt;
procedure ClearKbdBuffer;
var
Ch: Char;
begin
while KeyPressed do
Ch := ReadKey;
end;
- Utiliser les variables internes du clavier
En plus du tampon, le clavier dispose d'autres variables en mémoire. Parmi celles-ci, on trouve la position de la prochaine touche à lire dans le tampon ainsi que la position du premier emplacement libre dans le tampon. Pour vider le tampon, il suffit d'indiquer au clavier que la prochaine touche à lire est un emplacement libre.
La position de la prochaine touche à lire se trouve à l'adresse 0040:001A et celle du prochain emplacement libre à 0040:001C (ce sont deux Word). D'où le code :
procedure ClearKbdBuffer;
begin
MemW[Seg0040:$001A] := MemW[Seg0040:$001C];
end;
On peut aussi faire appel à l'assembleur (sauf DPMI ou Windows) :
procedure ClearKbdBuffer; assembler;
asm
mov es, 0040h
mov ax, es:[001Ch];
mov es:[001Ah], ax
end;
- Faire appel à l'interruption 21h
Cette dernière méthode à l'avantage de ne pas avoir d'adresse mémoire codée dans le programme. Elle s'appuie sur la fonction 0Ch de l'interruption 21h :
uses
Dos;
procedure ClearKbdBuffer;
var
Regs: Registers;
begin
Regs.ax := $0C00;
MsDos(Regs);
end;
On peut aussi faire appel à l'assembleur :
procedure ClearKbdBuffer; assembler;
asm
mov ax, 0C00h
int 21h
end;
Remarque :
- Sous Windows, on pourra parcourir la boucle des messages en éliminant tous les messages WM_KEYDOWN
|
|
auteur :
Hdd34 | Turbo Pascal ne sait malheureusement pas détecter les touches F11 et F12. Il faut l'aider un peu... Pour cela, il faut se servir de la fonction 10h de l'interruption 16h :
uses
Dos;
function ReadExtKey: Word;
var
Regs : registers;
KbdStatus: Byte absolute $0040:$0096;
begin
ReadExtKey := 0;
if KbdStatus and 16 = 0 then Exit;
Regs.ah := $10;
Intr ($16, Regs);
ReadExtKey := Regs.ax
end;
var
Key: Word;
begin
...
Key := ReadExtKey;
if Key = $8500 then
else if Key = $8600 then ;
...
end.
|
lien : Comment détecter l'appui sur les touches de direction ?
lien : Comment détecter les touches de contrôle ?
|
Consultez les autres F.A.Q's
Les sources présentés sur cette pages sont libre de droits,
et vous pouvez les utiliser à votre convenance. Par contre cette page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs.
Copyright ©2004
Developpez LLC. Tout droits réservés Developpez LLC.
Aucune reproduction, même partielle, ne peut être faite de ce site et de
l'ensemble de son contenu : textes, documents et images sans l'autorisation
expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à 3 ans
de prison et jusqu'à 300 000 E de dommages et intérets.
Cette page est déposée à la SACD.
|