коды getch и стрелки
Я пишу программу, которая использует getch()
для сканирования клавиш со стрелками. Мой код до сих пор:
switch(getch()) {
case 65: // key up
break;
case 66: // key down
break;
case 67: // key right
break;
case 68: // key left
break;
}
проблема в том, что когда я нажимаю 'A'
, 'B'
, 'C'
или 'D'
код также будет выполнен, потому что 65
- десятичный код 'A'
, etc...
есть ли способ проверить наличие клавиши со стрелкой без вызова других?
спасибо!
10 ответов
нажатием одной клавиши со стрелкой getch
будет толкать три значения в буфер:
'3'
'['
-
'A'
,'B'
,'C'
или'D'
таким образом, код будет примерно таким:
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 () возвращает два кода клавиш для клавиш со стрелками (и некоторых других специальных клавиш), как указано в комментарии FatalError. Сначала он возвращает 0 (0x00) или 224 (0xE0), а затем возвращает код, идентифицирующий нажатую клавишу.
для клавиш со стрелками он сначала возвращает 224, а затем 72 (вверх), 80 (вниз), 75 (влево) и 77 (вправо). Если клавиши со стрелками num-pad (с выключенным NumLock) нажаты, getch () сначала возвращает 0 вместо 224.
обратите внимание, что getch () никоим образом не стандартизирован, и эти коды могут отличаться от компилятора к компилятору. Эти коды возвращаются MinGW и Visual C++ в Windows.
удобная программа для просмотра действия getch () для различных клавиш:
#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);
}
это работает для MinGW и Visual C++. Эти компиляторы используют имя _getch () вместо getch (), чтобы указать, что это нестандартная функция.
Итак, вы можете сделать что-то вроде:
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 ... */
}
}
Итак, после много борьбы, я чудесным образом решена эта проблема everannoying ! Я пытался имитировать терминал linux и застрял в той части, где он хранит историю команд, к которой можно получить доступ, нажав клавиши со стрелками вверх или вниз. Я обнаружил, что ncurses lib трудно понять и медленно учиться.
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
Это смелый, но это многое объясняет. Удачи !
на keypad
позволит клавиатуре терминала пользователя разрешить интерпретацию функциональных клавиш как одного значения (т. е. без escape-последовательности).
как указано в man-странице:
опция клавиатуры включает клавиатуру терминала пользователя. Если включено (BF истинно), потребитель может отжать функциональную клавишу (как стрелка) и wgetch возвращает одно значение, представляющее функцию ключ, как в KEY_LEFT. Если отключено (bf FALSE), проклятия не лечит функциональные клавиши специально и программа должна интерпретировать escape сама последовательность. Если клавиатура в терминале может быть включена (сделано для передачи) и off (сделано для работы локально), включив эту опцию вызывает включение клавиатуры терминала при вызове wgetch. Этот значение по умолчанию для клавиатуры-false.
на самом деле, чтобы прочитать клавиши со стрелками, нужно прочитать его код сканирования. Ниже приведен код сканирования, сгенерированный клавишами со стрелками Нажмите (не отпустите клавишу)
когда блокировка num выключена
- слева E0 4B
- справа E0 4D
- До Е0 48
- Вниз E0 50
когда Num Lock находится на этих клавишах, предшествует Е0 2А
- байт Е0 является -32
- байт 48 72 вверх
-
байт 50 составляет 80 вниз
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; } }
в приведенном выше коде я предположил, что программист хочет переместить только 4 строки.
для решения, которое использует ncurses
с рабочим кодом и инициализацией ncurses см. getchar () возвращает то же значение (27) для клавиш со стрелками вверх и вниз
Я написал функцию, используя getch, чтобы получить код стрелки. это быстрый, нежели'dirty решения, но функция возвращает ASCII-код в зависимости от стрелка : Итог : -10 Вниз : -11 Справа : -12 Слева : -13
кроме того, с помощью этой функции вы сможете различать ESCAPE touch и клавиши со стрелками. Но вы должны нажать ESC 2 раз, чтобы активировать клавишу ESC.
вот код :
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;
}
Я просто стартер, но я создал char(for example "b")
, а я b = _getch();
(это библиотеки )
И проверьте
If (b == -32)
b = _getch();
и проверьте наличие ключей (72 вверх, 80 вниз, 77 вправо, 75 влево)
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);
}
}
Как насчет этого?
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();
}
}
}
(Если вы не можете понять, почему существует 224, попробуйте запустить этот код:)
#include <stdio.h>
#include <conio.h>
int main() {
while (1) {
if (kbhit()) {
printf("%d\n",getch());
}
}
}
но я не знаю, почему это 224. вы можете Написать комментарий, если знаете почему?