getch et les codes fléchés
j'écris un programme qui utilise getch()
pour scanner les touches fléchées. Mon code jusqu'à présent est:
switch(getch()) {
case 65: // key up
break;
case 66: // key down
break;
case 67: // key right
break;
case 68: // key left
break;
}
problème est que lorsque je presse 'A'
, 'B'
, 'C'
ou 'D'
le code sera également exécuté, parce que 65
est le code décimal pour 'A'
, etc...
Est-il un moyen de vérifier la présence d'une flèche sans appel les autres?
Merci!
10 réponses
en appuyant sur une touche de flèche getch
poussera trois valeurs dans le tampon:
-
'3'
-
'['
-
'A'
,'B'
,'C'
ou'D'
ainsi le code sera quelque chose comme ceci:
if (getch() == '3') { // if the first value is esc
getch(); // skip the [
switch(getch()) { // the real value
case 'A':
// code for arrow up
break;
case 'B':
// code for arrow down
break;
case 'C':
// code for arrow right
break;
case 'D':
// code for arrow left
break;
}
}
getch () renvoie deux keycodes pour les touches fléchées (et quelques autres touches spéciales), comme indiqué dans le commentaire de FatalError. Il retourne d'abord 0 (0x00) ou 224 (0xE0), puis renvoie un code identifiant la clé qui a été pressée.
pour les touches fléchées, il renvoie 224 d'abord suivi de 72 (up), 80 (down), 75 (left) et 77 (right). Si les touches fléchées num-pad (avec NumLock désactivé) sont enfoncées, getch () renvoie d'abord 0 au lieu de 224.
veuillez noter que getch () n'est pas standardisé, et que ces codes peuvent varier d'un compilateur à l'autre. Ces codes sont retournés par MinGW et Visual C++ sur Windows.
un programme pratique pour voir l'action de getch () pour différentes clés est:
#include <stdio.h>
#include <conio.h>
int main ()
{
int ch;
while ((ch = _getch()) != 27) /* 27 = Esc key */
{
printf("%d", ch);
if (ch == 0 || ch == 224)
printf (", %d", _getch ());
printf("\n");
}
printf("ESC %d\n", ch);
return (0);
}
cela fonctionne pour MinGW et Visual C++. Ces compilateurs utilisent le nom _getch () au lieu de getch () pour indiquer qu'il s'agit d'une fonction non standard.
So, vous pouvez faire quelque chose comme:
ch = _getch ();
if (ch == 0 || ch == 224)
{
switch (_getch ())
{
case 72:
/* Code for up arrow handling */
break;
case 80:
/* Code for down arrow handling */
break;
/* ... etc ... */
}
}
ainsi, après beaucoup de lutte, j'ai miraculeusement résolu cette question toujours passionnante ! J'ai essayé d'imiter un terminal linux et je me suis retrouvé coincé à la partie où il conserve un historique de commandes auquel on peut accéder en appuyant sur les touches fléchées vers le haut ou vers le bas. J'ai trouvé que les ncurses lib étaient douloureusement difficiles à comprendre et lents à apprendre.
char ch = 0, k = 0;
while(1)
{
ch = getch();
if(ch == 27) // if ch is the escape sequence with num code 27, k turns 1 to signal the next
k = 1;
if(ch == 91 && k == 1) // if the previous char was 27, and the current 91, k turns 2 for further use
k = 2;
if(ch == 65 && k == 2) // finally, if the last char of the sequence matches, you've got a key !
printf("You pressed the up arrow key !!\n");
if(ch == 66 && k == 2)
printf("You pressed the down arrow key !!\n");
if(ch != 27 && ch != 91) // if ch isn't either of the two, the key pressed isn't up/down so reset k
k = 0;
printf("%c - %d", ch, ch); // prints out the char and it's int code
c'est un peu audacieux mais ça explique beaucoup. Bonne chance !
le keypad
permettra au clavier du terminal de l'utilisateur de faire en sorte que les touches de fonction soient interprétées comme une seule valeur (c.-à-d. aucune séquence d'échappement).
comme indiqué dans la page de manuel:
l'option keypad active le keypad du terminal de l'utilisateur. Si activé (BF est TRUE), l'utilisateur peut appuyer sur une touche de fonction (telle qu'une touche de flèche) et wgetch renvoie une valeur unique représentant fonction key, comme dans KEY_LEFT. Si elle est invalide( BF est faux), les malédictions ne traitent pas les touches de fonction spécialement et le programme doit interpréter l'évasion les séquences de lui-même. Si le clavier du terminal peut être activé (fait pour transmettre) et off( fait pour travailler localement), en activant cette option provoque l'activation du clavier du terminal lorsque wgetch est appelé. Le valeur par défaut du clavier est faux.
en fait, pour lire les flèches, il faut lire son code de balayage. Voici le code scan généré par les touches fléchées presser (pas de sortie de touche)
Lorsque le Verrouillage numérique est désactivé
- Left E0 4B
- Right E04d
- Up E0 48
- Baisse E0 50
quand la serrure Num est sur ces touches se font précédés par E0 2A
- Octet E0 est de -32
- Byte 48 72
-
Octet de 50 à 80 vers le BAS
user_var=getch(); if(user_var == -32) { user_var=getch(); switch(user_var) { case 72: cur_sel--; if (cur_sel==0) cur_sel=4; break; case 80: cur_sel++; if(cur_sel==5) cur_sel=1; break; } }
dans le code ci-dessus, j'ai supposé que programmeur veut déplacer 4 lignes seulement.
pour une solution qui utilise la ncurses
avec le code de travail et de l'initialisation de l'interface ncurses voir getchar() renvoie la même valeur (27) pour le haut et bas touches de direction
j'ai écrit une fonction utilisant getch pour obtenir le code de flèche. c'est une solution rapide mais la fonction renvoie un code ASCII en fonction de la flèche : UP: -10 En baisse: -11 Droite: -12 Gauche: -13
de plus,avec cette fonction, vous serez en mesure de différencier le toucher D'évasion et les touches fléchées. Mais vous devez appuyer sur ESC 2 fois pour activer la touche ESC.
ici le code:
char getch_hotkey_upgrade(void)
{
char ch = 0,ch_test[3] = {0,0,0};
ch_test[0]=getch();
if(ch_test[0] == 27)
{
ch_test[1]=getch();
if (ch_test[1]== 91)
{
ch_test[2]=getch();
switch(ch_test[2])
{
case 'A':
//printf("You pressed the up arrow key !!\n");
//ch = -10;
ch = -10;
break;
case 'B':
//printf("You pressed the down arrow key !!\n");
ch = -11;
break;
case 'C':
//printf("You pressed the right arrow key !!\n");
ch = -12;
break;
case 'D':
//printf("You pressed the left arrow key !!\n");
ch = -13;
break;
}
}
else
ch = ch_test [1];
}
else
ch = ch_test [0];
return ch;
}
je suis juste un démarreur, mais j'ai créé un char(for example "b")
, et je fais b = _getch();
(c'est une commande de bibliothèque conio.h
)
Et vérifier
If (b == -32)
b = _getch();
Et de faire vérifier les touches (72, 80 vers le bas, 77 droit, de 75 à gauche)
void input_from_key_board(int &ri, int &ci)
{
char ch = 'x';
if (_kbhit())
{
ch = _getch();
if (ch == -32)
{
ch = _getch();
switch (ch)
{
case 72: { ri--; break; }
case 80: { ri++; break; }
case 77: { ci++; break; }
case 75: { ci--; break; }
}
}
else if (ch == '\r'){ gotoRowCol(ri++, ci -= ci); }
else if (ch == '\t'){ gotoRowCol(ri, ci += 5); }
else if (ch == 27) { system("ipconfig"); }
else if (ch == 8){ cout << " "; gotoRowCol(ri, --ci); if (ci <= 0)gotoRowCol(ri--, ci); }
else { cout << ch; gotoRowCol(ri, ci++); }
gotoRowCol(ri, ci);
}
}
et si on essayait ça?
void CheckKey(void) {
int key;
if (kbhit()) {
key=getch();
if (key == 224) {
do {
key=getch();
} while(key==224);
switch (key) {
case 72:
printf("up");
break;
case 75:
printf("left");
break;
case 77:
printf("right");
break;
case 80:
printf("down");
break;
}
}
printf("%d\n",key);
}
int main() {
while (1) {
if (kbhit()) {
CheckKey();
}
}
}
(si vous ne pouvez pas comprendre pourquoi il y a 224, alors essayez d'exécuter ce code: )
#include <stdio.h>
#include <conio.h>
int main() {
while (1) {
if (kbhit()) {
printf("%d\n",getch());
}
}
}
mais je ne sais pas pourquoi c'est 224. pouvez-vous écrire un commentaire si vous savez pourquoi?