2012-05-05 26 views
27

Piszę program, który używa getch() do skanowania w poszukiwaniu klawiszy strzałek. Mój kod do tej pory:kody pobierania i strzałek

switch(getch()) { 
    case 65: // key up 
     break; 
    case 66: // key down 
     break; 
    case 67: // key right 
     break; 
    case 68: // key left 
     break; 
} 

Problem jest to, że po naciśnięciu 'A', 'B', 'C' lub 'D' kod będzie również wykonywane, ponieważ 65 jest kod dziesiętny dla 'A', etc ...

Czy czy istnieje sposób sprawdzenia, czy nie ma klawiszy strzałek, aby zadzwonić do innych?

Dzięki!

+1

Minęły lata, odkąd się z tym bawiłem, to wcale nie jest zestandaryzowane ... ale z powrotem, kiedy grałem z 'getch()', dla "specjalnych" kluczy faktycznie wrócił dwa razy. Za pierwszym razem zwrócił 0, a następnie kod specjalnego klucza, aby można było go odróżnić od innych kluczy. – FatalError

+0

'65' jest tylko dla znaku' A'. Aby otrzymać te klucze, musisz użyć kodów kontrolnych. Zobacz ten post. http://stackoverflow.com/questions/2876275/what-are-the-ascii-values-of-up-down-left-right –

Odpowiedz

48

naciskając jeden klawisz strzałki getch pchnie trzy wartości do bufora:

  • '\033'
  • '['
  • 'A', 'B' , 'C' lub 'D'

Więc kod będzie coś takiego:

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; 
    } 
} 
+1

Czy istnieje wersja "getch" w wersji Unix-Land, gdzie ta odpowiedź jest poprawna? Kody tutaj są tym, co można uzyskać z większości terminali podczas używania 'getchar'. Nie są one tym, co można uzyskać z 'getch' z' '. –

+1

'case 'A'' powinno być' case' A ': ', również dla' case' D'' – Nik

+0

Czy wiesz, dlaczego w moim terminalu widzę" O "zamiast" ["jako drugiej litery? FYI, używam zsh w sesji tmux. Dzięki! – Muffo

15

Funkcja getch() zwraca dwa kody klawiszy dla klawiszy strzałek (i kilku innych specjalnych klawiszy), jak wspomniano w komentarzu do FatalError. Najpierw zwraca 0 (0x00) lub 224 (0xE0), a następnie zwraca kod identyfikujący naciśnięty klawisz.

Dla klawiszy strzałek zwraca najpierw 224, następnie 72 (w górę), 80 (w dół), 75 (w lewo) i 77 (w prawo). Jeśli klawisze strzałek z kluczem numerycznym (z wyłączonym NumLock wyłączone) są naciśnięte, getch() zwraca najpierw 0 zamiast 224.

Należy pamiętać, że getch() nie jest w żaden sposób standaryzowany, a kody te mogą różnić się od kompilatora do kompilator. Kody te są zwracane przez MinGW i Visual C++ w systemie Windows.

przydatny program, aby zobaczyć działanie getch() dla różnych kluczy jest:

#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); 
} 

Działa to dla MinGW i Visual C++. Kompilatory używają nazwy _getch() zamiast getch(), aby wskazać, że jest to funkcja niestandardowa.

Tak, można zrobić coś takiego:

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 ... */ 
    } 
} 
1

Tak, po alot walki, ja cudem rozwiązać ten problem everannoying! Próbowałem naśladować terminal linuxowy i utknąłem w części, w której przechowuje historię poleceń, do której można uzyskać dostęp, naciskając klawisze strzałek w górę lub w dół. Zauważyłem, że biblioteka ncurses jest bolesna i trudna do zrozumienia.

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 

To trochę odważne, ale wyjaśnia dużo. Powodzenia !

1

W celu odczytania klawiszy strzałek należy odczytać kod skanowania. Poniżej przedstawiono kod skanowania generowany przez klawisze strzałek prasy (nie klucz release)

Gdy tryb num lock jest wyłączony

  • Lewy E0 4B
  • Prawy E0 4D
  • Up E0 48
  • W dół E0 50

Gdy Num Lock jest na tych kluczy uzyskać poprzedzone E0 2A

  • Byte E0 jest -32
  • Byte 48 jest 72 UP
  • Bajt 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; 
    
        } 
    } 
    

W abo Kod ve Założę, że programista chce przenieść tylko 4 linie.

+0

Proszę wyjaśnić swoją odpowiedź? –

1

keypad pozwoli klawiaturze terminala użytkownika na umożliwienie interpretacji klawiszy funkcyjnych jako pojedynczej wartości (tj. Bez sekwencji unikowej).

Jak podano w manualu:

Opcja klawiatura umożliwia klawiaturę terminala użytkownika. Jeśli włączono (bf ma wartość PRAWDA), użytkownik może nacisnąć klawisz funkcyjny (taki jak klawisz strzałki ), a wgetch zwraca pojedynczą wartość reprezentującą klucz funkcji , podobnie jak w KEY_LEFT. Jeśli wyłączona (bf jest FALSE), curses nie traktuje specjalnie klawiszy funkcyjnych , a program musi interpretować sekwencje escape same. Jeśli klawiatura w terminalu może być włączona (wykonana jako ) i wyłączona (wykonana do pracy lokalnie), włączenie tej opcji powoduje, że klawiatura terminala jest włączana po wywołaniu wgetch. Domyślna wartość dla klawiatury to .

0

Pisałem funkcję używając getch dostać kod strzałki. to rozwiązanie quick'n'dirty ale funkcja zwróci kod ASCII w zależności od klawisza ze strzałką: UP: -10 dół: -11 RIGHT: -12 LEWO: -13

Ponadto z tej funkcji , będziesz w stanie rozróżnić dotyk ESCAPE i klawisze strzałek. Ale musisz nacisnąć klawisz ESC 2, aby aktywować klawisz ESC.

tutaj kod:

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; 
} 
0

Jestem tylko rozrusznik, ale I'v stworzył char(for example "b"), a ja b = _getch(); (polecenie jego conio.h biblioteki) I sprawdzić

If (b == -32) 
b = _getch(); 

Sprawdź też, czy nie ma kluczy (72 w górę, 80 w dół, 77 w prawo, 75 w lewo)