2012-05-05 66 views
27

Tôi đang viết một chương trình đang sử dụng getch() để quét các phím mũi tên. Mã của tôi cho đến nay là:mã và mã mũi tên

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

Vấn đề là khi tôi bấm 'A', 'B', 'C' hoặc 'D' mã cũng sẽ được thực hiện, bởi vì 65 là mã thập phân cho 'A', vv ...

Is có cách nào để kiểm tra một phím mũi tên mà không cần gọi cho người khác?

Cảm ơn!

+1

Đã lâu rồi kể từ khi tôi chơi với điều này, nó không phải là chuẩn bit ít nhất ... nhưng trở lại khi tôi chơi với 'getch()', cho các phím "đặc biệt" nó thực sự trả về hai lần. Lần đầu tiên nó trả về một 0, sau đó một mã cho khóa đặc biệt, để bạn có thể nói nó ngoài các phím khác. – FatalError

+0

'65' chỉ dành cho ký tự' A'. Bạn phải sử dụng các mã điều khiển để nhận các khóa này. Xem bài đăng này. http://stackoverflow.com/questions/2876275/what-are-the-ascii-values-of-up-down-left-right –

Trả lời

48

Bằng cách nhấn một phím mũi tên getch sẽ đẩy ba giá trị vào bộ đệm:

  • '\033'
  • '['
  • 'A', 'B' , 'C' hoặc 'D'

Vì vậy, các mã sẽ được một cái gì đó như thế này:

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

Có một số phiên bản vùng đất Unix của 'getch' mà câu trả lời này là đúng không? Các mã ở đây là những gì bạn muốn nhận được từ hầu hết các thiết bị đầu cuối khi sử dụng 'getchar'. Họ không phải là những gì bạn sẽ nhận được từ 'getch' từ ''. –

+1

'case 'A'' nên là' case' A ': ', cũng cho' case' D'' – Nik

+0

Bạn có biết tại sao trong terminal của tôi tôi thấy chữ 'O' thay vì '[' làm ký tự thứ hai? FYI, tôi đang chạy zsh bên trong một phiên tmux. Cảm ơn! – Muffo

15

Hàm getch() trả về hai mã khóa cho các phím mũi tên (và một số phím đặc biệt khác), như đã đề cập trong phần bình luận của FatalError. Nó trả về 0 (0x00) hoặc 224 (0xE0) đầu tiên, và sau đó trả về một mã xác định khóa đã được nhấn.

Đối với các phím mũi tên, nó trả về 224 trước, sau đó là 72 (lên), 80 (xuống), 75 (trái) và 77 (bên phải). Nếu nhấn phím mũi tên num-pad (với NumLock), getch() trả về 0 đầu tiên thay vì 224.

Xin lưu ý rằng getch() không được chuẩn hóa theo bất kỳ cách nào và các mã này có thể khác nhau từ trình biên dịch sang trình biên dịch. Các mã này được trả về bởi MinGW và Visual C++ trên Windows.

Một chương trình tiện dụng để xem hành động của getch() cho các phím khác nhau là:

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

này làm việc cho MinGW và Visual C++. Các trình biên dịch này sử dụng tên _getch() thay vì getch() để chỉ ra rằng nó là một hàm không chuẩn.

Vì vậy, bạn có thể làm điều gì đó như:

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

Vì vậy, sau rất nhiều cuộc đấu tranh, tôi một cách kỳ diệu giải quyết vấn đề everannoying này! Tôi đã cố gắng bắt chước một thiết bị đầu cuối Linux và bị kẹt ở phần mà nó giữ một lịch sử lệnh có thể được truy cập bằng cách nhấn lên hoặc xuống các phím mũi tên. Tôi thấy ncurses lib rất khó hiểu và chậm chạp để học.

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 

Đó là loại đậm nhưng nó giải thích rất nhiều. Chúc may mắn !

1

Thực ra, để đọc các phím mũi tên, bạn cần phải đọc mã quét của nó. Sau đây là mã quét được tạo ra bởi các phím mũi tên báo chí (không chính phát hành)

Khi num Khóa tắt

  • Left E0 4B
  • Ngay E0 4D
  • Up E0 48
  • Xuống E0 50

Khi Num Lock đang bật các phím này được bắt đầu bằng E0 2A

  • Byte E0 là -32
  • Byte 48 là 72 UP
  • Byte 50 là 80 XUỐNG

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

Trong abo đã mã tôi đã giả định lập trình muốn di chuyển 4 dòng chỉ.

+0

Bạn có thể giải thích câu trả lời của mình không? –

1

keypad sẽ cho phép bàn phím của thiết bị đầu cuối của người dùng cho phép các phím chức năng được hiểu là một giá trị đơn lẻ (ví dụ: không có chuỗi thoát).

Như đã trình bày trong man page:

Các tùy chọn bàn phím cho phép bàn phím của thiết bị đầu cuối của người dùng. Nếu kích hoạt (bf là TRUE), người dùng có thể nhấn phím chức năng (chẳng hạn như một phím mũi tên ) và wgetch trả về một giá trị đại diện cho hàm , như trong KEY_LEFT. Nếu bị vô hiệu hóa (bf là FALSE), các lời nguyền sẽ không xử lý các khóa chức năng đặc biệt và chương trình phải giải thích thoát khỏi các chuỗi của chính nó. Nếu bàn phím trong thiết bị đầu cuối có thể được bật (thực hiện để truyền) và tắt (được thực hiện để hoạt động tại địa phương), bật tùy chọn này làm cho bàn phím đầu cuối được bật khi gọi wgetch. Giá trị mặc định cho bàn phím là sai.

0

Tôi đã viết một hàm sử dụng getch để lấy mã mũi tên. đó là một giải pháp quick'n'dirty nhưng hàm sẽ trả về một mã ASCII tùy thuộc vào phím mũi tên: UP: -10 XUỐNG: -11 QUYỀN: -12 LEFT: -13

Hơn nữa, với chức năng này , bạn sẽ có thể phân biệt được cảm ứng ESCAPE và các phím mũi tên. Nhưng bạn phải nhấn ESC 2 lần để kích hoạt phím ESC.

đây mã:

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

Tôi chỉ là một khởi động, nhưng I'v ​​tạo ra một char(for example "b"), và tôi làm b = _getch(); (một conio.h thư viện của nó lệnh) Và kiểm tra

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

Và hãy kiểm tra các phím (72 lên, 80 xuống, 77 phải, 75 trái)

Các vấn đề liên quan