【问题标题】:Autohotkey, assotiate key with objectAutohotkey,将键与对象关联
【发布时间】:2015-12-01 16:45:54
【问题描述】:

这是我的脚本的一部分。如果程序没有运行,它会通过热键运行程序,或者在其他情况下显示/隐藏它的窗口。

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"{ 行为。如果有人会根据上面的模式重写代码(或提出更好的模式),我将非常感激。

【问题讨论】:

    标签: autohotkey keymapping


    【解决方案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
       }
    }
    

    【讨论】:

    • 我试图修改我的代码,但它不起作用。在第二个语句中,我有一些不存在的热键 #n 错误。 fn1 := Func("RunOrToggleApp").Bind(appDesc)Hotkey, % "#" appDesc.key, % fn1, on
    • 在上面的答案中添加了完整的功能版本。
    • 谢谢,原来问题是我有ahk v1.15,更新到1.22后它工作正常。
    【解决方案2】:

    该死,lintalist 更快。 :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
    }
    

    【讨论】:

      【解决方案3】:

      这是我的解决方案,虽然我更喜欢 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
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2017-07-03
        • 1970-01-01
        • 1970-01-01
        • 2014-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多