V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
o0OoO0o
V2EX  ›  问与答

[AutoHotkey] 怎样让空格键做修饰键时是 shift,单独按时仍然是空格?

  •  
  •   o0OoO0o · 2017-09-13 11:29:38 +08:00 · 3306 次点击
    这是一个创建于 2419 天前的主题,其中的信息可能已经有所发展或是发生改变。

    希望最终效果:

    ① 按 空格+a/b/../z/1/2/../0/鼠标左键 /右键,映射成 shift+a/b/../z/1/2/../0/鼠标左键 /右键
    ② 按 空格+鼠标左键 框选,映射成 shift+鼠标左键 框选
    ③ 单独按 空格,就还是空格

    试了两种方法,都不行:

    第一种:
    space::LShift,但这种方法,效果③(单独按空格仍然是空格)不知道怎么办
    第二种:一条一条的写

    Space:: SendInput, {Space}
    Space & 1:: SendInput, +1
    ……
    Space & 0:: SendInput, +0
    Space & LButton:: SendInput, +{LButton}
    Space & RButton:: SendInput, +{RButton}
    Space & a:: SendInput, +a
    ……

    但这种写法,效果②就是 框选怎么写呢?

    求助大家

    13 条回复    2017-09-14 17:46:28 +08:00
    Kasine
        1
    Kasine  
       2017-09-13 11:45:24 +08:00 via Android
    space::shift
    space::send {space}
    o0OoO0o
        2
    o0OoO0o  
    OP
       2017-09-13 11:49:37 +08:00
    @Kasine #1 这样 空格+鼠标左键 就不能映射成 shift+鼠标左键了
    按下空格的一瞬间,就触发 send {space}了,按住不放就会持续触发……
    Kasine
        3
    Kasine  
       2017-09-13 11:57:22 +08:00 via Android
    @o0OoO0o 松开才执行的
    o0OoO0o
        4
    o0OoO0o  
    OP
       2017-09-13 12:23:37 +08:00   ❤️ 1
    @Kasine #3 谢谢,我实际用记事本测试了:

    全局这样写:
    space::LShift
    space::Send {space}
    那么单按空格不会输出空格(下面那行无效)

    按窗口这样写:
    #IfWinActive ahk_exe notepad.exe
    space::LShift
    space::Send {space}
    那么修饰键是无效的,即中间那行无效;且按下的瞬间,就触发空格
    loading
        5
    loading  
       2017-09-13 12:37:18 +08:00 via Android
    一起来客制化机械键盘吧,这个直接键盘固件给你支持。(不是量产的那些)
    Kasine
        6
    Kasine  
       2017-09-13 13:26:23 +08:00
    @o0OoO0o #4 抱歉,很久没写 ahk 了,有些地方记不清楚了
    DiamondbacK
        7
    DiamondbacK  
       2017-09-13 14:47:47 +08:00   ❤️ 1
    Space::Shift
    Space Up::
    SendInput {Shift Up}
    if (A_PriorKey = "Space"
    and GetKeyState("Ctrl") = 0
    and GetKeyState("Shift") = 0
    and GetKeyState("Alt") = 0)
    {
    SendInput {Space}
    }
    Return

    可以实现三个效果,但是注意 Space 仅仅在单独按下——修饰键也需处于松开状态——并松开后才会触发 SendInput {Space}。所以无法保持修饰键+Space 的组合键功能。
    另外 Space 一旦按下就会触发 Shift 按下状态,所以输入法状态下 1) 会导致中英文切换,2) 选字时无法使用 Space 上屏。
    问题 1) 可以修改其中一行来补救:

    Space::Shift
    Space Up::
    SendInput {Shift Up}
    if (A_PriorKey = "Space"
    and GetKeyState("Ctrl") = 0
    and GetKeyState("Shift") = 0
    and GetKeyState("Alt") = 0)
    {
    SendInput {Shift}{Space}
    }
    Return

    也就在是单独的 Space Up 发生后,先多 Send 一个 Shift,连续两次 Shift 就把中英文状态切回去了。
    同时也使得选字时 Space 可以直接上屏,但是选中的不一定等于真正的 Space 所会选中的项目。

    我没有用 GetKeyState 来检测 Win 键的状态,因为我自己实测检测不出来,返回值为空。
    o0OoO0o
        8
    o0OoO0o  
    OP
       2017-09-13 15:08:59 +08:00
    @DiamondbacK #7 太感谢!原来 A_PriorKey = "Space"是关键啊,已经大体能用了
    但有个小小问题:按 空格+鼠标左键 框选(或者仅仅 Lbutton 单击)的时候,因为 A_PriorKey 不能检测鼠标左键单击,所以还是会误发空格——也就是说,②和③没有协调一致——这个有办法检测吗?
    DiamondbacK
        9
    DiamondbacK  
       2017-09-13 16:58:16 +08:00
    @o0OoO0o
    用一个 Hotkey 捕捉鼠标左键的点击,并通过全局变量 sLButtonClicked 跟踪。

    Space::Shift
    Space Up::
    SendInput {Shift Up}
    if (A_PriorKey = "Space"
    and GetKeyState("Ctrl") = 0
    and GetKeyState("Shift") = 0
    and GetKeyState("Alt") = 0)
    {
    if (sLButtonClicked = 1) {
    sLButtonClicked = 0
    } else {
    SendInput {Shift}{Space}
    }
    }
    Return
    *~LButton::
    if (GetKeyState("Shift") = 1) {
    sLButtonClicked = 1
    }
    Return
    cy18
        10
    cy18  
       2017-09-14 09:11:05 +08:00 via Android
    o0OoO0o
        11
    o0OoO0o  
    OP
       2017-09-14 13:53:59 +08:00
    @DiamondbacK #9 完美!真是水平悬殊啊,昨天我试了俩小时都没解决……大神却分分钟搞定,真的太谢谢了!
    DiamondbacK
        12
    DiamondbacK  
       2017-09-14 16:25:22 +08:00
    @o0OoO0o 我研究了也不止分分钟……
    DiamondbacK
        13
    DiamondbacK  
       2017-09-14 17:46:28 +08:00   ❤️ 1
    @o0OoO0o
    加入了对 Win 键状态的检查,原先我犯了低级错误,不知道 AutoHotkey 不认 Win,只认 LWin 和 RWin。

    Space::Shift
    Space Up::
    SendInput {Shift Up}
    if (A_PriorKey = "Space"
    and GetKeyState("Ctrl") = 0
    and GetKeyState("Shift") = 0
    and GetKeyState("Alt") = 0
    and GetKeyState("LWin") = 0
    and GetKeyState("RWin") = 0)
    {
    if (sLButtonClicked = 1) {
    sLButtonClicked = 0
    } else {
    SendInput {Shift}{Space}
    }
    }
    Return
    *~LButton::
    if (GetKeyState("Shift") = 1) {
    sLButtonClicked = 1
    }
    Return
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5443 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 09:03 · PVG 17:03 · LAX 02:03 · JFK 05:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.