英文:
Toggle Multiple Hotkeys with Loop
问题
我对AutoHotKey有些陌生。我创建了一个可切换的宏,将WASD键映射到箭头键。
原始代码有效,但我尝试使用一个循环来启用热键,但目前出现了“不存在的热键”错误。我该如何修复这个循环,使其像下面硬编码的噩梦一样工作?
for i in macros {
Hotkey, % keys[i], % macros[i], % state ; <<< 这一行导致了错误
}
arrowsActive := 0
; CTRL + WASD --> 箭头键
Enter::
arrowsActive := not arrowsActive
macros := [arrowUp1, arrowLeft1, arrowDown1, arrowRight1, arrowUp2, arrowLeft2, arrowDown2, arrowRight2]
keys := [W, A, S, D, W, A, S, D]
state = Off
if arrowsActive {
state = On
}
for i in macros {
Hotkey, % keys[i], % macros[i], % state
}
;Hotkey, W, arrowUp1, state
;Hotkey, A, arrowLeft1, state
;Hotkey, S, arrowDown1, state
;Hotkey, D, arrowRight1, state
;Hotkey, W Up, arrowUp2, state
;Hotkey, A Up, arrowLeft2, state
;Hotkey, S Up, arrowDown2, state
;Hotkey, D Up, arrowRight2, state
Return
arrowUp1:
send, {Up Down}
Return
arrowUp2:
send, {Up Up}
Return
arrowLeft1:
send, {Left Down}
Return
arrowLeft2:
send, {Left Up}
Return
arrowDown1:
send, {Down Down}
Return
arrowDown2:
send, {Down Up}
Return
arrowRight1:
send, {Right Down}
Return
arrowRight2:
send, {Right Up}
Return
希望这可以帮助你修复错误并让循环工作。
英文:
I'm somewhat new to AutoHotKey. I made a toggleable macro that maps the WASD keys to the arrow keys.
The original code works but I'm trying to enable the hotkeys with a loop which is currently giving me a Nonexistent Hotkey error. How can I fix this loop, so that it works like the hard-coded nightmare below it?
for i in macros {
Hotkey, % keys[i], % macros[i], % state ; <<< This line is causing the error
}
arrowsActive := 0
; CTRL + WASD --> arrow keys
Enter::
arrowsActive := not arrowsActive
macros := [arrowUp1, arrowLeft1, arrowDown1, arrowRight1, arrowUp2, arrowLeft2, arrowDown2, arrowRight2]
keys := [W, A, S, D, W, A, S, D]
state = Off
if arrowsActive {
state = On
}
for i in macros {
Hotkey, % keys[i], % macros[i], % state
}
;Hotkey, W, arrowUp1, state
;Hotkey, A, arrowLeft1, state
;Hotkey, S, arrowDown1, state
;Hotkey, D, arrowRight1, state
;Hotkey, W Up, arrowUp2, state
;Hotkey, A Up, arrowLeft2, state
;Hotkey, S Up, arrowDown2, state
;Hotkey, D Up, arrowRight2, state
Return
arrowUp1:
send, {Up Down}
Return
arrowUp2:
send, {Up Up}
Return
arrowLeft1:
send, {Left Down}
Return
arrowLeft2:
send, {Left Up}
Return
arrowDown1:
send, {Down Down}
Return
arrowDown2:
send, {Down Up}
Return
arrowRight1:
send, {Right Down}
Return
arrowRight2:
send, {Right Up}
Return
答案1
得分: 2
你问题的根源似乎出在你对AHK v1中的旧版语法与表达式语法的理解上。这里还有我以前关于旧版语法和表达式语法的回答,你可能会从中找到一些帮助。
但现在来说实际的问题:
macros := [arrowUp1, arrowLeft1, arrowDown1, arrowRight1, arrowUp2, arrowLeft2, arrowDown2, arrowRight2]
keys := [W, A, S, D, W, A, S, D]
你在这里是在一个表达式中,所以你尝试创建一个包含来自变量arrowUp1
,arrowLeft1
,...,W
,A
,...的数组值。但这些变量不存在,所以你最终创建了两个充满空元素的数组。什么都没有。
你原本想做的是:
macros := ["arrowUp1", "arrowLeft1", ...
keys := ["W", "A", ...
另外,在你的keys
数组中,你没有为键的第二半部分指定w up
,a up
等。
除此之外,它会工作。但当然,实现可以更好。
让我们改进一下:
remaps := { w: "Up"
, a: "Left"
, s: "Down"
, d: "Right" }
Enter::
; 将这个变量的值存储在全局作用域中,以便在此热键子程序的后续运行中引用它
global arrowsActive := !arrowsActive
for key, arrowKey in remaps
{
loop, 2
{
; 第一次循环用于按下时的热键
; 第二次循环用于释放键时的热键
keyFunction := Func("SendKey").bind(arrowKey, (A_Index - 1) ? true : false)
Hotkey, % key ((A_Index - 1) ? " Up" : ""), % keyFunction, % arrowsActive ? "On" : "Off"
}
}
return
SendKey(key, release := false)
{
SendInput, % "{" key (release ? " Up" : "") "}"
}
有关理解代码的有用文档链接:
答案还利用了一个事实,即你不需要指定Down
热键。如果你有例如热键a
和a up
,热键a
在Windows的重复键功能触发并在按住键时重复按键时被调用。然后a up
在释放a
时被调用。
如果关于答案还有其他不清楚的地方,请随时提问。
英文:
The root of your problems seem to be with understanding the legacy vs expression syntax in AHK v1. Here is also a previous answer of mine about legacy syntax and expression syntax. You might find some help from it.
But now to the actual problems:
macros := [arrowUp1, arrowLeft1, arrowDown1, arrowRight1, arrowUp2, arrowLeft2, arrowDown2, arrowRight2]
keys := [W, A, S, D, W, A, S, D]
You're in an expression here, so what you're trying to do is create an array that includes values from the variables arrowUp1
, arrowLeft1
, ..., W
, A
,... But those variables don't exist, so you end up creating two arrays that are full of absolutely nothing. Just empty elements.
What you were trying to do is
macros := ["arrowUp1", "arrowLeft1", ...
keys := ["W", "A", ...
Also in your keys
array, you didn't specify w up
, a up
,... for the second half of the keys.
Other than that, it would work. But of course, the implementation could be a lot better.
Let's make it better:
remaps := { w: "Up"
, a: "Left"
, s: "Down"
, d: "Right" }
Enter::
;store this variable's value in the global scope, so it can be referred to
;on the following runs of this hotkey subroutine
global arrowsActive := !arrowsActive
for key, arrowKey in remaps
{
loop, 2
{
;first loop for hotkeys when pressing down
;second loop for hotkeys when releasing keys
keyFunction := Func("SendKey").bind(arrowKey, (A_Index - 1) ? true : false)
Hotkey, % key ((A_Index - 1) ? " Up" : ""), % keyFunction, % arrowsActive ? "On" : "Off"
}
}
return
SendKey(key, release := false)
{
SendInput, % "{" key (release ? " Up" : "") "}"
}
Useful documentation links to understand the code:
The answer also utilizes the fact that you shouldn't need to specify a Down
hotkey. If you have e.g. hotkeys a
and a up
, the hotkey a
gets called everything Windows' repeat key functionality triggers and repeats a key while you hold it down. And then a up
gets called when a is released.
If something else is unclear about the answer, feel free to ask.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论