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

kle*_*vre 13 c ncurses

如何获得Ctrl,ShiftAltgetch()ncurses?
我无法得到它的工作得到Ctrl,ShiftAltgetch()使用ncurses的?我想念那个男人的东西吗?

Tec*_*eks 16

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

  • 首先,对于"普通键",例如可打印键,您可以轻松检测到移位,因为它是大写的.

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

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

  • 对于CTRL,您将在实际的键名称前面得到一个"^".例如^ R代表密钥18

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

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

就是这样.在明确地说"不能"之前先想想.也许有一种方式不太明显.

  • 实际上这种方法不起作用. (4认同)
  • 这是因为 Python 绑定进一步“烹饪”了代码。 (3认同)
  • 这不利于编写可跨多种键盘布局使用的代码。例如,“ Shift + 2”可以根据布局生成不同的字符。 (2认同)

Leo*_*erd 6

(粗略地复制我在Curses中如何获得Shift + X/Alt + X键的答案)

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

也就是说,如果你感觉特别勇敢,你可以尝试我的libtermkey,它至少会正确地解析像Ctrl- 的东西arrow.

最后,如果你觉得勇敢,甚至可以运行我写的终端,pangoterm,其中有通用的方式来编码任何任意修改的Unicode键,因此它可以区分Ctrl- mEnter,Ctrl- Shift- aCtrl- a等等......

但是,除了这些,答案仍然是"你不能".


use*_*237 5

至少对于控制修饰符,有一个简单的解决方案。诅咒是从vi源代码派生而来的,您可以在其中找到以下内容(请参阅 https://github.com/nt-roff/ex-1.1/blob/master/ex.h第77行和https://github.com /nt-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 */
Run Code Online (Sandbox Code Playgroud)

CTRL在代码中可能已经定义了依赖于所使用的包含项,也可能尚未定义。

  • 我没有尝试过这个,但很高兴知道为什么这被否决了。 (2认同)

Tho*_*key 5

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

请参阅 ncurses 常见问题解答如何使用移位或控制修饰符?一个很长的答案。

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

  • 将实际功能键乘以 Shift 和 Control 修饰符的组合,或者乘以
  • 使用基于 xterm 的 PC 风格功能键的名称(shift 为 2、alt 为 3、control 为 5 等)来提供信息。

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

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

这主要适用于特殊键(功能键、编辑键和光标键)。对于常规键,人们可能会认为它keyname给出了一些特殊的行为,但阅读说明却没有:

  • 它报告 ASCII 控制字符(您可以使用iscntrl宏来完成),并且
  • 对元做出假设(仅对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.
Run Code Online (Sandbox Code Playgroud)

它对应于一个控制序列,见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.
Run Code Online (Sandbox Code Playgroud)

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