如何使用getch()ncurses获取Ctrl,Shift或Alt?

时间:2012-03-17 14:05:51

标签: c ncurses

如何使用getch() ncurses获取 Ctrl Shift Alt ? 我使用ncurses得到 Ctrl Shift Alt getch()是不行的?我想念那个男人的东西吗?

7 个答案:

答案 0 :(得分:16)

令人惊讶的是,有时候正确的答案会被降级,并且答案是权威的"放弃升级......有了一点创造力,key_name实际上拥有正确的键来解决这个问题,但有一点需要注意 - 同时按下SHIFT / ALT / CTRL和其他键:

  • 首先,对于"普通键"例如可打印的,你可以很容易地检测到移位,因为它是大写的。

  • 对于特殊密钥,例如KEY_LEFT,您将看到选择SHIFT时生成的代码实际上是KEY_SLEFT。同上KEY_RIGHT。不幸的是,KEY_UP / KEY_DOWN没有这样的运气,这似乎是SHIFT所不感兴趣的。所以你可以通过返回的char来区分getch() - KEY_S ..意味着移位被按下了。

  • 对于ALT(至少没有被X或Aqua Windowmanager困住),keyname会将密钥转换为M ......某事。

  • 对于CTRL,你会得到一个" ^"在实际的密钥名称之前。 E.g ^ R代码为18

所以你现在可以通过一个简单的片段找出你的switch(getch)语句等的密钥代码:

ch = getch(); endwin(); printf("KEY NAME : %s - %d\n", keyname(ch),ch);

那是那个。在明确地说" can&#t; t"之前先想想。也许这种方式不太明显。

答案 1 :(得分:6)

(粗略地从How to get Shift+X / Alt+X keys in Curses ?复制我的答案)

长话短说 - 你不能。修饰键只是 - 修饰符。它们本身并不存在,它们会修改您可能按下的其他(打印)键。

那就是说,如果你感觉特别勇敢,你可以尝试我的libtermkey,它至少会正确解析 Ctrl - arrow 等。

最后如果你感觉更勇敢,你可以运行我写的终端pangoterm,它有通用的方法来编码任意任意修改的Unicode密钥,因此它可以区分 Ctrl - m 输入 Ctrl - Shift - a 来自 Ctrl < / kbd> - a 等...

然而,除了这些,答案仍然是“你不能”。

答案 2 :(得分:3)

至少对于控制修饰符,有一个简单的解决方案。 Curses源自vi源代码,您可以在其中找到以下内容(请参阅 https://github.com/n-t-roff/ex-1.1/blob/master/ex.h第77行和https://github.com/n-t-roff/ex-1.1/blob/master/ex_vops.c第445行:

#ifndef CTRL
#define CTRL(c) ((c) & 037)
#endif

switch(getch()) {
case CTRL('r'):
    /* key ctrl-r (i.e. ^R) pressed */

依赖于已使用的包含CTRL可能已经或可能尚未在您的代码中定义。

答案 3 :(得分:2)

(部分)与@leonerd达成一致,ncurses将 为您提供这些键,因为它们被用作其他键的修饰符(忽略ASCII 转义字符,有些人混淆了 Alt 键。可以告诉某些特定设备提供此信息(例如,console_ioctl(4)中记录的Linux控制台),但这不是ncurses将为您解决的问题。

请参阅ncurses常见问题解答How can I use shift- or control-modifiers?获取详细答案。

但简短:ncurses没有告诉你是否使用了一个给定的修饰符(除了众所周知的使用 shift 的特殊情况),而是它的终端描述提供了

的信息
  • 通过shift和control-modifiers的组合或
  • 将实际功能键相乘
  • 使用基于xterm的PC风格功能键的名称(shift为2,alt为3,control为5等),以提供信息。

有两种方法,因为第一种使用不超过60个功能键的数组(对于移位和控制组合足够好),而另一种只使用用户定义的名称)。

所有这些修改后的密钥都有多个字节;在ncurses中使用keypad()(当然)的应用程序将获得一个数字。在后一种情况下,密钥代码在运行时确定。

主要适用于特殊键(功能键,编辑键和光标键)。对于常规键,可以假设keyname给出了一些特殊行为,但是读取它没有的描述:

  • 它报告ASCII控制字符(您可以使用iscntrl宏)和
  • 对meta进行假设(仅对xterm,您可能会使用的终端有用),
  • shift 修饰符没有任何帮助。

终端......都在内部提供修改器信息,但终端通常无法将此信息传递给应用程序。 xterm可以使用modifyOtherKeys资源

执行此操作
   modifyOtherKeys (class ModifyOtherKeys)
           Like modifyCursorKeys, tells xterm to construct an escape
           sequence for other keys (such as "2") when modified by
           Control-, Alt- or Meta-modifiers.  This feature does not apply
           to function keys and well-defined keys such as ESC or the
           control keys.  The default is "0":

           0    disables this feature.

           1    enables this feature for keys except for those with well-
                known behavior, e.g., Tab, Backarrow and some special
                control character cases, e.g., Control-Space to make a
                NUL.

           2    enables this feature for keys including the exceptions
                listed.

对应于控制序列,见XTerm Control Sequences

CSI > Ps; Ps m
          Set or reset resource-values used by xterm to decide whether
          to construct escape sequences holding information about the
          modifiers pressed with a given key.  The first parameter iden-
          tifies the resource to set/reset.  The second parameter is the
          value to assign to the resource.  If the second parameter is
          omitted, the resource is reset to its initial value.
            Ps = 0  -> modifyKeyboard.
            Ps = 1  -> modifyCursorKeys.
            Ps = 2  -> modifyFunctionKeys.
            Ps = 4  -> modifyOtherKeys.

但是(作为特定于xterm的功能),没有理由在ncurses中使用它:它会不必要地使getch复杂化。

答案 4 :(得分:0)

你不能,任何主要的终端模拟器都没有扩展来实现它。

如果您正在假设X11环境,您可以使用X11函数来检索它,但这完全是另一个问题。

答案 5 :(得分:0)

您可以调用key_name( c )getch()生成的密钥转换为显示ctrl-modifier状态的内容。

例如,如果按ctrl-r:

,此代码显示“^ R”
while( true )
{
   char c = getch();
   if ( ERR == c )
      break;

   const char *name = key_name( c );

   move( 2, 2 );
   clear();
   printw( "You entered: %s             ", name );
   refresh();

}

答案 6 :(得分:0)

我知道这很老,但对于仍在寻找的人... 您可以在Windows上执行此操作(至少在我的版本上)。 只需将getch解释为类似字节的整数,然后解释为字符串即可。

str(getchvariablehere)

例如,键盘上的Ctrl + A为1。 这有点乏味,但是您可以使用此方法检查任何组合。

我的措辞可能不正确,但是这种方法似乎适用于无法将字节显示为任意unicode的光栅字体。