在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;
}
答案 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
。