2015-09-05 34 views
1

這是我的腳本的一部分。如果它沒有運行,它將通過熱鍵運行程序,或者在其他情況下顯示/隱藏它的窗口。Autohotkey,與對象分離鑰匙

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個程序,編輯起來非常困難。

我想它是這樣的(半僞代碼)工作:

appDescs := Object() 
appDescs.Insert(new ProgramDesc("cmd.exe", "ConsoleWindowClass", "s")) 
appDescs.Insert(new ProgramDesc("calc.exe", "CalcFrame", "c")) 


#"some key"{ 
    find key in appDescs array and RunOrToggleActive(for correspondig program) 
} 

!#"some key"{ 
    find key in appDescs array and RunNewInstance(for correspondig program) 
} 

RunOrToggleActive(programDesc) { 
    ... 
} 

RunNewInstance(programDesc) { 
    ... 
} 

Class ProgramDesc { 
    __New(path, wndClass, key) { 
     this.path := path, this.wndClass := wndClass, this.key := key 
    } 
} 

我不知道如何實現#"some key"{行爲。如果有人會根據上面的模式重寫代碼(或者建議更好的代碼),我會非常感激。

回答

1

您可以使用熱鍵命令http://ahkscript.org/docs/commands/Hotkey.htm並使用它來使所有熱鍵跳轉到標籤或調用函數。在那裏你可以使用內置變量A_ThisHotkey來找出哪個熱鍵被按下,並找到你需要的其他數據。

隨着標籤:

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 
    } 
} 
+0

我試圖修改我的代碼,但它不起作用。在第二個聲明中,我沒有找到熱鍵#n的錯誤。 'fn1:= Func(「RunOrToggleApp」)。綁定(appDesc)' 'Hotkey,%「#」appDesc.key,%fn1,on' – grabantot

+0

在上面的答案中增加了完整的函數版本。 – lintalist

+0

謝謝,原來問題是我已經ahk v1.15,更新到1.22後,它工作正常。 – grabantot

1

該死的,皮塔爾人的速度更快。 :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 
} 
0

這裏是我的解決方案,雖然我很喜歡lintalist的一個更好的。

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 
    } 
}