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

如何使用getch()ncurses获取Ctrl、Shift或Alt?,c,ncurses,C,Ncurses,如何使用getch()ncurses获取Ctrl、Shift或Alt键? 我无法使用ncurses通过getch()获得Ctrl、Shift或Alt键?我是否错过了《男人》中的某些东西?你不能,在任何主要的终端模拟器中都没有扩展来实现它 如果您假设的是X11环境,您可以使用X11函数来检索它,但这是一个完全不同的问题。(大致复制我的答案) 长话短说——你不能。修改器关键点只是那个-修改器。它们本身并不存在,它们修改了您可能按下的其他(打印)键 这就是说,如果你觉得特别勇敢,你可以试试我的,它至少

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

我无法使用ncurses通过
getch()
获得Ctrl、Shift或Alt键?我是否错过了《男人》中的某些东西?

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

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

(大致复制我的答案)

长话短说——你不能。修改器关键点只是那个-修改器。它们本身并不存在,它们修改了您可能按下的其他(打印)键

这就是说,如果你觉得特别勇敢,你可以试试我的,它至少能正确解析像Ctrl-arrow这样的东西

最后,如果你觉得更勇敢,你可以运行我写的终端,它有通用的方法来编码任意修改的Unicode键,这样它就可以区分Ctrl-m和Enter,Ctrl-Shift-a和Ctrl-a,等等


但是,除此之外,答案仍然是“您不能”。

您可以调用
key\u name(c)
将从
getch()
生成的键转换为显示ctrl修饰符状态的内容

例如,如果按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();

}

令人惊讶的是,有时正确的答案会被降级,而“权威”放弃的答案会被提升。。。凭借一点创造力,key_name实际上掌握了解决这一问题的正确方法,但有一点需要注意:SHIFT/ALT/CTRL与其他键同时按下:

  • 首先,对于“普通键”,例如可打印键,您可以很容易地检测到shift,因为它是大写的

  • 对于特殊键,例如KEY_LEFT,您将看到选择SHIFT时生成的代码实际上是KEY_SLEFT。右键同上。不幸的是,键向上/键向下没有这样的运气,这似乎不受移位的影响。因此,您可以通过返回的char与getch()进行区分-键。。这意味着按下了shift键

  • 对于ALT(至少X或Aqua Windowmanager未捕获的内容),keyname会将该键转换为M。。。什么

  • 对于CTRL键,您将在实际键名之前获得一个“^”。例如,图例18的R

因此,您现在可以通过一个简单的代码片段来找出switch(getch)语句等的关键代码:

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

就这样。在明确地说“不行”之前先想一想。也许有一种方法不那么明显。

至少对于控制修饰符,有一个简单的解决方案。Curses是从vi源代码中派生出来的,您可以在其中找到以下内容(参见 第77行和第445行):

取决于使用的包含键,CTRL键可能在代码中定义,也可能尚未定义。

同意(部分)@leonerd,ncurses将仅提供这些键,因为它们被用作其他键的修改器(忽略ASCII转义字符,有些人将其与Alt键混淆)。可以告诉某些特定设备提供此信息(例如,中所述的Linux控制台),但这不是ncurses将为您解决的问题

有关详细答案,请参阅ncurses常见问题解答

但简短地说:ncurses不会告诉您是否使用了给定的修饰符(除了众所周知使用shift的特殊情况),而是其终端描述通过以下两种方式提供信息:

  • 将实际功能键乘以换档和控制修改器的组合,或乘以
  • 使用基于xterm的PC风格功能键(shift为2、alt为3、control为5等)的名称来提供信息
有两种方法,因为第一种方法使用不超过60个功能键的数组(足够用于换档和控制组合),而另一种方法仅使用用户定义的名称)

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

这主要适用于特殊键(功能键、编辑键和光标键)。对于常规键,可以假设它提供了一些特殊行为,但阅读描述时却没有:

  • 它报告ASCII控制字符(您可以使用
    iscntrl
    宏执行此操作),以及
  • 对meta(仅对您可能使用的终端的
    xterm
    有用)进行假设,以及
  • 对shift修改器不提供任何帮助
终端的数量。。。它们都有内部可用的修改器信息,但终端通常没有将此信息传递给应用程序的方法
xterm
可以使用资源执行此操作

   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特有的特性),没有理由在ncurses中使用它:它将不必要地使
getch

复杂化,我知道这已经过时了,但对于仍在寻找它的人来说。。。 您可以在Windows上执行此操作(至少在我的版本上)。 只需将getch解释为类似整数的字节,然后将其解释为字符串

str(getchvariablehere)
例如,在我的键盘上,Ctrl+A是1。 这有点乏味,但是你可以用这个方法检查任何组合


我的措辞可能不正确,但此方法似乎适用于不能以任意unicode显示字节的光栅字体。

Control、shift和alt不生成输入,它们修改其他输入。@SethCarnegie:我记得许多游戏中,您可以使用这些键中的任何一个进行单独操作。我相信每个键都有某种独特的扫描代码。@KerrekSB但它们不会生成stdin的输入。您可以测试它们是否关闭(即Windows具有
GetAsyncKeyState
),但这是在键盘上工作,而不是像
getch
那样在输入上工作。这个问题应该重新表述。现在主要是一个句子的字面重复,这对书面语没有帮助
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.
str(getchvariablehere)