例如,在 Visual Studio Express 2013 中,许多格式化快捷方式已“折叠”到Ctrl+ 中E。要评论选择,可以按住Ctrl、点击E、点击C,然后松开Ctrl。

如果我发送这样的输入,我会写
SendInput {Ctrl Down}ec{Ctrl Up}
Run Code Online (Sandbox Code Playgroud)
但是如何将该序列变成热键呢?我试过
{Ctrl Down}EC{Ctrl Up}::
MsgBox, "Hello, world!"
Return
Run Code Online (Sandbox Code Playgroud)
但当然,这会导致语法错误:

终于想通了。
替换^e为第一个所需的按键。替换3为第二个所需按键的 ASCII 索引。这强制Ctrl通过两次击键保持,否则取消。
~$Ctrl UP::
ChordIsBroken := True
Return
^e::
ChordIsBroken := False
Input, OutputVar, L1 M
If (!ChordIsBroken && Asc(OutputVar) = 3)
{
MsgBox "Hello, World!"
}
Else
{
SendInput %OutputVar%
}
Return
Run Code Online (Sandbox Code Playgroud)
要将其调整为Shift代替Ctrl,您必须替换Ctrls,删除M,并进行更简单的比较,例如OutputVar = C代替Asc(OutputVar) = 3。不确定如何将其扩展到Alt并且Win您可能必须尝试L2或类似的东西。
Input似乎是一个明显的起点。Input要求 AHK 等待用户输入,例如
^e::
Input, OutputVar, L1 ; "L1" means wait for 1 keystroke then continue.
If (OutputVar = "c")
{
MsgBox, "Hello, World!"
}
Return
Run Code Online (Sandbox Code Playgroud)
上面的消息框在CtrlEthen上触发C。但是我们正在寻找CtrlC,所以让我们解决这个问题:
^e::
Input, OutputVar, L1 M ; "M" allows storage of modified keystrokes (^c).
If (Asc(OutputVar) = 3) ; ASCII character 3 is ^c.
{
MsgBox "Hello, World!"
}
Return
Run Code Online (Sandbox Code Playgroud)
现在我们在按下CtrlEthen 时有一个消息框CtrlC。但这有一个问题:即使我在两次击键之间松开 Ctrl,消息框也会触发。那么,我们如何本质上检测{Ctrl Up}中间输入?你不能只检查入口——
^e::
if (!GetKeyState("Ctrl"))
{
Return
}
Input, OutputVar, L1 M
; ...
Run Code Online (Sandbox Code Playgroud)
——也不能仅仅在输入后检查——
^e::
Input, OutputVar, L1 M
if (!GetKeyState("Ctrl"))
{
Return
}
; ...
Run Code Online (Sandbox Code Playgroud)
——你甚至不能同时做这两件事,因为不管怎样,你都会错过{Ctrl Up}while 阻塞输入。
然后我查看了文档以Hotkey获得灵感。自定义组合运算符&,看起来很有前途。但遗憾的是,
^e & ^c::
; ...
Run Code Online (Sandbox Code Playgroud)
导致编译错误;显然,仅&用于组合未修改的按键。
终于到了UP,这就是我最终取得突破的地方。我重新定义了Ctrl'sUP来设置一个可以防止消息框触发的切换!
$Ctrl::Send {Ctrl Down} ; The $ prevents an infinite loop. Although this
$Ctrl UP:: ; line seems redundant, it is in fact necessary.
ChordIsBroken := True ; Without it, Ctrl becomes effectively disabled.
Send {Ctrl Up}
Return
^e::
ChordIsBroken := False
Input, OutputVar, L1 M
If (!ChordIsBroken && Asc(OutputVar) = 3)
{
MsgBox "Hello, World!"
}
Return
Run Code Online (Sandbox Code Playgroud)
现在,当我按下CtrlE,然后松开Ctrl,然后按下CtrlC,没有任何反应,正如预期的那样!
还有最后一件事需要解决。在“取消”(“断弦”)时,我希望所有击键都恢复正常。但是在上面的代码中Input,无论是和弦断裂还是无关的辅助击键,都必须在返回之前“吃掉”一次击键。添加Else案例很好地解决了这个问题:
Else
{
SendInput %OutputVar%
}
Run Code Online (Sandbox Code Playgroud)
所以,你有它 - AutoHotkey 中的“和弦”。(虽然,我不会完全称其为“和弦”。更像是带有低音线的旋律;-)
@hippibruder 慷慨地指出,我可以$Ctrl::通过使用~使$Ctrl UP::非阻塞来避免定义。这允许一些简化!(有关最终结果,请参阅顶部的 tl;dr 部分。)
还有一件事。如果,也许,在“取消”(“断弦”)时,您想发出第一次击键,即 单独发出CtrlE,只需将其添加到Else块中,
Else
{
SendInput ^e
SendInput %OutputVar%
}
Run Code Online (Sandbox Code Playgroud)
并且不要忘记将热键更改为
$^e::
Run Code Online (Sandbox Code Playgroud)
以避免无限循环。
| 归档时间: |
|
| 查看次数: |
2988 次 |
| 最近记录: |