Autohotkey 自动热键,将键与对象关联
这是我剧本的一部分。如果程序未运行,则通过热键运行程序,或者在其他情况下显示/隐藏其窗口Autohotkey 自动热键,将键与对象关联,autohotkey,keymapping,Autohotkey,Keymapping,这是我剧本的一部分。如果程序未运行,则通过热键运行程序,或者在其他情况下显示/隐藏其窗口 ConsolePath := "cmd.exe" ConsoleWndClass := "ConsoleWindowClass" CalculatorPath := "calc.exe" CalculatorWndClass := "CalcFrame" #s:: RunOrToggleActive(ConsolePath, ConsoleWndClass) return #c:: RunOr
ConsolePath := "cmd.exe"
ConsoleWndClass := "ConsoleWindowClass"
CalculatorPath := "calc.exe"
CalculatorWndClass := "CalcFrame"
#s::
RunOrToggleActive(ConsolePath, ConsoleWndClass)
return
#c::
RunOrToggleActive(CalculatorPath, CalculatorWndClass)
return
RunOrToggleActive(path, wndClass) {
SplitPath, path, process
Process, Exist, %process%
If !ErrorLevel {
Run, %path%
}
else {
ToggleActive(wndClass)
}
}
ToggleActive(wndClass)
{
IfWinNotActive, % "ahk_class " wndClass
{
WinActivate, % "ahk_class " wndClass
}
else
{
WinMinimize, % "ahk_class " wndClass
}
}
工作正常,但这种方法的问题是添加新程序和热键非常费力。必须添加2个变量,复制热键处理程序代码,替换热键,替换变量。如果我想为每个程序添加新的热键函数(比如!#s和!#c,以运行另一个程序实例,即使它已经在运行),我必须再次重复新代码。我的实际脚本有7个程序,很难编辑
我希望它像这样工作(半伪代码):
我不知道如何实现
#“some key”{
行为。如果有人愿意按照上述模式重写代码(或建议更好的模式)非常感谢。您可以使用热键命令,让所有热键跳转到标签或调用函数。在这里,您可以使用内置变量a_thishhotkey
查找按下的热键,并查找所需的其他数据
带标签:
appDescs := Object()
appDescs.Insert(new ProgramDesc("cmd.exe", "ConsoleWindowClass", "s"))
appDescs.Insert(new ProgramDesc("calc.exe", "CalcFrame", "c"))
for k, v in appDescs {
Hotkey, % "#" v.key, RunOrToggleActive
Hotkey, % "!#" v.key, RunNewInstance
}
RunOrToggleActive:
; ....
Return
RunNewInstance:
; ....
Return
具有功能
appDescs := Object()
appDescs.Insert(new ProgramDesc("cmd.exe", "ConsoleWindowClass", "s"))
appDescs.Insert(new ProgramDesc("calc.exe", "CalcFrame", "c"))
fn1 := Func("RunOrToggleActive")
fn2 := Func("RunNewInstance")
for k, v in appDescs {
Hotkey, % "#" v.key, % fn1, on
Hotkey, % "!#" v.key, % fn2, on
}
RunOrToggleActive() {
; ....
}
RunNewInstance() {
; ....
}
编辑:如果您喜欢函数版本,这将是完整的脚本
#SingleInstance, force
appDescs := Object()
appDescs.Insert(new ProgramDesc("cmd.exe", "ConsoleWindowClass", "s"))
appDescs.Insert(new ProgramDesc("calc.exe", "CalcFrame", "c"))
fn1 := Func("RunOrToggleActive").Bind(appDescs)
fn2 := Func("RunNewInstance").Bind(appDescs)
for k, v in appDescs {
Hotkey, % "#" v.key, % fn1, on
Hotkey, % "!#" v.key, % fn2, on
}
RunOrToggleActive(o) {
for k, v in o
If ("#" v.key = A_ThisHotkey)
path:=v.path,wndClass:=v.wndClass
SplitPath, path, process
Process, Exist, %process%
If !ErrorLevel {
Run, %path%
}
else {
ToggleActive(wndClass)
}
}
RunNewInstance(o) {
for k, v in o
If ("!#" v.key = A_ThisHotkey)
Run % v.path
}
ToggleActive(wndClass)
{
IfWinNotActive, % "ahk_class " wndClass
{
WinActivate, % "ahk_class " wndClass
}
else
{
WinMinimize, % "ahk_class " wndClass
}
}
Class ProgramDesc {
__New(path, wndClass, key) {
this.path := path, this.wndClass := wndClass, this.key := key
}
}
该死的,林惇斯更快。:D
好吧,下面是我想到的:
AddWinToggle("#s","cmd.exe","ConsoleWindowClass") ;toggle hotkey
AddRunHotkey("#c","calc.exe") ;hotkey that starts a new instance each time
;RemoveHotkey("#s") ;remove a hoktey
AddWinToggle(hk, path, wndClass) {
fn := func("RunOrToggleActive").Bind(path,wndClass)
Hotkey, % hk, % fn
If !ErrorLevel
Return True
}
AddRunHotkey(hk, path) {
fn := func("RunNew").Bind(path,wndClass)
Hotkey, % hk, % fn
If !ErrorLevel
Return True
}
RemoveHotkey(hotkey) {
Hotkey, %hotkey%, Off
If !ErrorLevel
Return True
}
RunNew(path) {
Run, % path
}
RunOrToggleActive(path, wndClass) {
SplitPath, path, process
Process, Exist, %process%
If !ErrorLevel
Run, %path%
Else
ToggleActive(wndClass)
}
ToggleActive(wndClass) {
IfWinNotActive, % "ahk_class " wndClass
WinActivate, % "ahk_class " wndClass
Else
WinMinimize, % "ahk_class " wndClass
}
这是我的解决方案,虽然我更喜欢林惇主义者的方案
global appDescs := Object()
appDescs.Insert(new AppDesc("n", "Notepad.exe", "Notepad"))
appDescs.Insert(new AppDesc("s", "cmd.exe", "ConsoleWindowClass"))
appDescs.Insert(new AppDesc("c", "calc.exe", "CalcFrame"))
#n::
#s::
#c::
stringsplit, splitted_, A_ThisHotkey
appDesc := AppDescByKey(splitted_2)
RunOrToggleApp(appDesc)
return
RunOrToggleApp(appDesc) {
DetectHiddenWindows, on
path := appDesc.path
SplitPath, path, process
Process, Exist, %process%
If !ErrorLevel {
Run, %path%
}
else {
ToggleActive(appDesc.wndClass)
}
}
ToggleActive(wndClass)
{
IfWinNotActive, % "ahk_class " wndClass
{
WinActivate, % "ahk_class " wndClass
}
else
{
WinMinimize, % "ahk_class " wndClass
}
}
AppDescByKey(key) {
for i, appDesc in appDescs {
if (key = appDesc.key) {
return appDesc
}
}
}
Class AppDesc {
__New(key, path, wndClass) {
this.key := key, this.path := path, this.wndClass := wndClass
}
}
我试图修改我的代码,但它不起作用。由于第二条语句中的某些原因,我的热键不存在。
fn1:=Func(“RunOrToggleApp”).Bind(appDesc)
热键,%“\appDesc.key,%fn1,on
在上面的答案中添加了完整的函数版本。谢谢,原来问题是我有ahk v1.15,在更新到1.22后,它工作正常。
global appDescs := Object()
appDescs.Insert(new AppDesc("n", "Notepad.exe", "Notepad"))
appDescs.Insert(new AppDesc("s", "cmd.exe", "ConsoleWindowClass"))
appDescs.Insert(new AppDesc("c", "calc.exe", "CalcFrame"))
#n::
#s::
#c::
stringsplit, splitted_, A_ThisHotkey
appDesc := AppDescByKey(splitted_2)
RunOrToggleApp(appDesc)
return
RunOrToggleApp(appDesc) {
DetectHiddenWindows, on
path := appDesc.path
SplitPath, path, process
Process, Exist, %process%
If !ErrorLevel {
Run, %path%
}
else {
ToggleActive(appDesc.wndClass)
}
}
ToggleActive(wndClass)
{
IfWinNotActive, % "ahk_class " wndClass
{
WinActivate, % "ahk_class " wndClass
}
else
{
WinMinimize, % "ahk_class " wndClass
}
}
AppDescByKey(key) {
for i, appDesc in appDescs {
if (key = appDesc.key) {
return appDesc
}
}
}
Class AppDesc {
__New(key, path, wndClass) {
this.key := key, this.path := path, this.wndClass := wndClass
}
}