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' и т. Д. …

Есть ли способ проверить клавишу со стрелкой без вызова других?

Благодаря!

Нажав одну клавишу getch стрелкой, getch выталкивает три значения в буфер:

  • '\033'
  • '['
  • 'A' , 'B' , 'C' или 'D'

Таким образом, код будет выглядеть примерно так:

 if (getch() == '\033') { // 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  #include  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 ... */ } } 

Итак, после многих битв, я чудесным образом решил эту вечную проблему! Я пытался подражать терминалу 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 в 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-последовательности).

Как указано на странице руководства:

Опция клавиатуры включает клавиатуру пользовательского терминала. Если включено (bf is TRUE), пользователь может нажать функциональную клавишу (например, стрелку), а wgetch возвращает одно значение, представляющее функциональный ключ, как в KEY_LEFT. Если отключено (bf – FALSE), curses не обрабатывает функциональные клавиши специально, и программа должна интерпретировать сами escape-последовательности. Если клавиатура в терминале может быть включена (сделана для передачи) и выключена (сделана для работы локально), включение этой опции приводит к включению клавиатуры терминала при вызове wgetch. Значение по умолчанию для клавиатуры – false.

Собственно, для чтения клавиш со стрелками нужно прочитать его код сканирования. Ниже приведен код сканирования, сгенерированный клавишами со стрелками, нажатием (не клавишей)

Когда num Lock отключен

  • Слева E0 4B
  • Правый E0 4D
  • Вверх E0 48
  • Вниз E0 50

Когда Num Lock находится на этих клавишах, ему предшествует E0 2A

  • Байт E0 равен -32
  • Байт 48 равен 72 UP
  • Байт 50 равен 80 DOWN

     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 для получения кода стрелки. это быстрое решение, но функция вернет код ASCII в зависимости от клавиши со стрелкой: UP: -10 DOWN: -11 RIGHT: -12 LEFT: -13

Кроме того, с помощью этой функции вы сможете различать касание ESCAPE и клавиши со стрелками. Но вы должны нажать 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(); (его команда conio.h ) и проверьте

 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  #include  int main() { while (1) { if (kbhit()) { printf("%d\n",getch()); } } } 

но я не знаю, почему это 224. Вы можете написать комментарий, если знаете почему?

Interesting Posts

Получить все веб-элементы управления определенного типа на странице

Находите диапазон диапазонов дат в пределах одной таблицы, для конкретного пользователя MySQL

Как вручную перезапустить графические драйверы?

Как удалить Cerber3 ransomware и расшифровать файлы .cerber3

Установите / снимите флажок в окне datagridview

C # WebBrowser Control Proxy

Устранение неполадок, связанных с подключением к Интернету через Wi-Fi на OS X

Сделайте так, чтобы Outlook не выбирал первую почту в папке «Входящие»

Использование атрибута «требуется» HTML5 для группы флажков?

Преимущества авто в параметрах шаблона в C ++ 17

Ошибка сборки maven: невозможно найти компилятор Javac в: jre или jdk issue

В чем разница между контекстом Persistence с областью действия и контекстом Extended Persistence?

Homebrew устанавливает конкретную версию формулы?

Уязвимость парольного пароля на SSH-сервере не будет работать?

Программно осветить цвет

Давайте будем гением компьютера.