在ncurses中捕捉控制+键的正确方法

时间:2017-05-11 18:55:26

标签: ncurses

在ncurses中捕获控件+键的正确方法是什么? 当前我正在定义这样的控制:

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

它工作正常,但问题是我无法同时捕获C-j和ENTER,这是因为:

   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 个答案:

答案 0 :(得分:2)

尝试nonl

  

nl nonl 例程控制底层显示设备          在输入时将返回键转换为换行符,以及它是否将换行符转换为返回值和换行符换行符(在任何一种情况下,           call addch('\n') 相当于返回和换行          虚拟屏幕)。最初,这些翻译确实发生了。如果你使用nonl禁用它们,curses将能够更好地利用它          换行功能,可以加快光标移动速度。还有,诅咒          然后将能够检测到返回键。

进一步阅读:getch手册页的Notes section

  

通常,KEY_ENTER表示由Enter键发送的字符          数字键盘:

     
      
  • 终端说明列出了最有用的密钥
  •   
  • 常规键盘上的Enter键已由。处理          用于回车和换行的标准ASCII字符,
  •   
  • 取决于是否调用nl或nonl,按下“Enter”          常规键盘可以返回回车或换行,          最后

  •   
  • “输入或发送”是此密钥的标准说明。

  •   

解决了有关换行/回车翻译的问题。后续评论提醒您注意,手册页提供了Initialization部分的基本建议:

  

获取一次一次的字符输入而不回显(大多数交互式,          面向屏幕的程序想要这个),应该是以下顺序          使用:

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

并且OP的示例程序未使用cbreak(或raw)。 cbreak的手册页说

  

通常,tty驱动程序缓冲键入的字符,直到换行符或          回车是打字的。 cbreak 例程会禁用行缓冲          并擦除/删除字符处理(中断和流控制字符不受影响),使用户立即输入字符          可用于该计划。 nocbreak 例程将终端返回到          正常(熟)模式。

     

最初,终端可能处于cbreak模式,也可能不处于cbreak模式          遗传;因此,程序应明确调用 cbreak nocbreak 大多数使用curses的交互式程序设置了cbreak模式。   请注意, cbreak 会覆盖 raw 。 (有关讨论,请参阅curs_getch(3x)   这些例程如何与 echo noecho 进行互动。)

此外,您可以在curs_getch阅读

  

如果keypad为TRUE,并且按下了一个功能键,则为该标记   返回功能键而不是原始字符:

     
      
  • 预定义的功能键在<curses.h>中列为宏          值超出8位字符范围。他们的名字以 KEY_ 开头。
  •   

也就是说,如果程序调用{​​{1}},curses将只返回KEY_ENTER

keypad

为了便于讨论,以下是一个示例,解决了截至5月17日您的示例程序的一些问题:

keypad(stdscr, TRUE);

也就是说,您必须在#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; } 之前致电keypad,而 getch 返回的值不是字符(无法打印{ {1}})。

使用通常的终端描述在Linux控制台上运行,您将只看到数字小键盘 Enter 的回车符,因为该描述不使用应用程序模式。 Linux控制台支持应用程序模式,可以编写相应的描述。作为快速检查(有差异......),您可以设置KEY_ENTER以查看 %c