2017-05-11 57 views
1

在ncurses中捕捉控制+鍵的正確方法是什麼? 目前的即時通訊做它定義這樣的控制:捕捉控制的正確方法+在ncurses中的鍵

#define ctl(x) ((x) & 0x1f) 

它工作正常,但問題是,我不能趕上CJ,並在同時進入,這是因爲:

j = 106 = 1101010 
0x1f = 31 = 0011111 
1101010 & 0011111 = 0001010 = 10 = ENTER key.. 

所以..我該如何抓住它? 謝謝!

- 編輯: 如果我嘗試下面的代碼, 我不能夠正確地捕捉回車鍵,甚至沒有在數字鍵盤。輸入捕獲爲ctrl-j。

#include <stdio.h> 
#include <ncurses.h> 
#define ctrl(x) ((x) & 0x1f) 

int main(void) { 
    initscr(); 
    int c = getch(); 
    nonl(); 
    switch (c) { 
     case KEY_ENTER: 
      printw("key: %c", c); 
      break; 
     case ctrl('j'): 
      printw("key: ctrl j"); 
      break; 
    } 
    getch(); 
    endwin(); 
    return; 
} 

新的代碼:

#include <stdio.h> 
#include <ncurses.h> 
#define ctrl(x)   ((x) & 0x1f) 

int main(void) { 
    initscr(); 
    int l = -1; 
    int c = getch(); 
    cbreak(); 
    noecho(); 
    nonl(); 
    keypad(stdscr, TRUE); 
    switch (c) { 
     case KEY_ENTER: 
      printw("key: %c", c); 
      break; 
     case ctrl('j'): 
      printw("key: ctrl j"); 
      break; 
    } 
    printw("\nnow press a key to end"); 
    getch(); 
    endwin(); 
    return; 
} 

回答

1

嘗試nonl

nlnonl例程控制底層顯示裝置 是否轉換了返回鍵入換行符上輸入,以及是否翻譯(換句話說, call addch('\n')在 虛擬屏幕上的回報和換行等價物)。最初,這些翻譯確實發生。如果您使用nonl禁用它們,則curses將能夠更好地使用換行功能,從而加快光標移動速度。此外,curses 將能夠檢測到返回鍵。

此外閱讀:getch手冊頁面的Notes section

通常,KEY_ENTER表示通過輸入鍵上 發送的數字小鍵盤的字符(或多個):

  • 的終端描述列出了最有用的按鍵,
  • 常規鍵盤上的Enter鍵已經由 對於回車和換行標準的ASCII字符,
  • 根據NL或NONL是否被調用時,按下「Enter」鍵的 常規鍵盤上可能會返回一個回車或換行符, 最後

  • 「輸入或發送」是此密鑰的標準描述。

,解決約換行/回車翻譯的問題。後隨註釋是一個提醒指出,手冊中Initialization部分給出了基本的建議:

要獲得字符以一次一個輸入,而不回顯(最具互動性, 屏幕爲導向的計劃想要這個) ,下面的順序應該是 使用:

 initscr(); cbreak(); noecho(); 

和OP的示例程序沒有使用cbreak(或raw)。爲cbreak的手冊頁說

通常,tty驅動緩衝區,直到一個新行或 回車鍵入鍵入的字符。 cbreak例程禁用行緩衝 和擦除/終止字符處理(中斷和流量控制字符不受影響),使用戶立即輸入用戶鍵入 程序。例程將終端返回到 正常(熟)模式。

最初,終端可能會或可能不處於cbreak模式,因爲模式是 繼承;因此,程序應明確地呼叫cbreaknocbreak大多數使用curses的交互式程序設置cbreak模式。 請注意,cbreak覆蓋raw。 (有關這些程序如何與echonoecho互動討論 見curs_getch(3x)。)

此外,在curs_getch你可以閱讀

如果keypad是真實的,功能鍵被按下時,返回該功能鍵的令牌而不是原始字符:

  • 預定義的功能鍵在<curses.h>中列爲宏 ,值超出8位字符範圍。他們的名字以KEY_開頭。

也就是說,詛咒只會返回KEY_ENTER如果程序調用keypad

keypad(stdscr, TRUE); 

爲了討論方便,這裏是您的示例程序作爲一個實例固定的一些問題5月17日:

#include <stdio.h> 
#include <ncurses.h> 
#define ctrl(x)   ((x) & 0x1f) 

int 
main(void) 
{ 
    int c; 
    initscr(); 
    keypad(stdscr, TRUE); 
    cbreak(); 
    noecho(); 
    nonl(); 
    c = getch(); 
    switch (c) { 
    case KEY_ENTER: 
     printw("\nkey_enter: %d", c); 
     break; 
    case ctrl('j'): 
     printw("\nkey: ctrl j"); 
     break; 
    default: 
     printw("\nkeyname: %d = %s\n", c, keyname(c)); 
     break; 
    } 
    printw("\nnow press a key to end"); 
    getch(); 
    endwin(); 
    return 0; 
} 

也就是說,你必須getch之前調用keypad,並且返回的值對於KEY_ENTER不是字符(它不能用%c打印)。

運行Linux控制檯與通常的終端描述上,你將看到數字鍵盤僅回車輸入,因爲這說明不使用應用模式。 Linux控制檯不支持應用程序模式,並且可以編寫相應的描述。作爲快速檢查(有差異...),您可以設置TERM=vt100以查看KEY_ENTER

+0

如果我設置nonl,那麼我不能再捕獲輸入密鑰。我用ncurses.h的KEY_ENTER宏捕捉它。編輯:是我定義ctrl宏的方式正確嗎? –

+0

使用nonl()編輯上面的一段新代碼; –

+0

再次編輯,使用鍵盤,cbreak和noecho添加一個新的示例程序。相同的結果:ENTER被捕獲爲C-j .. –