想要AutoIt3 HotKeySet来模拟AutoHotKey应用程序过滤

时间:2015-06-14 10:39:09

标签: autohotkey autoit

目标

我正在构建一个通用解决方案,用于使用AutoIt3高级控制任意程序UI,通过按下各种键或发出命令来调用。

零件

  • TargetUI - 通过发送点击和按键来控制的程序
  • MainAu3 - 执行发送的AutoIt程序
  • MainIni - 包含控制位置和专用表示法中的其他信息的文件,还包含热键信息。所有信息都特定于特定的TargetUI - 即。每个TargetUI的一个MainIni
  • KeyHookScript - 可选吗? AutoIt或AutoHotKey脚本

事实

  • HotKeySet() - AutoIt功能允许设置和取消设置系统范围的热键
  • AutoHotKey - 脚本语言 - 允许通过#IfWinActive
  • 对热键进行应用过滤
  • MainAu3目前设计用于获取由某些KeyHookScript提供的命令参数
  • MainAu3调用很慢,因为在启动时解析了MainIni,这是necc。由于计划目标

问题

  • 由于MainAu3的调用速度很慢,一个选项是让它在后台运行并拥有自己的keyhooks,或让KeyHookScript以某种方式与它进行通信
  • MainAu3和MainIni将有多个实例 - 每个TargetUI的一个实例。如果在每个MainAu3中使用HotKeySet(),这会导致冲突,除非每次TargetUIs获得焦点时设置和取消设置 - 这似乎是在寻找麻烦

预期方法

  • 看起来我需要一个监控应用程序的MainAu3Manager,并确保正确运行MainAu3 / MainIni。它还需要维护用AutoHotKey编写的Singleton(?)KeyHookScript

问题

  • 根据具有焦点并且是TargetUI的应用程序尝试通过每个MainAu3替换HotKeySet / Unset是多么不明智?
  • 鉴于这是一个糟糕的方法,哪种通信方法最好与正在运行的MainAu3s交谈?
  • 通过_IsPressed在AutoIt中创建自己的挂钩机制有多难,这会产生一个"轮询问题"如果它在每个MainAu3中频繁运行

沟通方法

这些都是我能想到的,我希望它快速可靠,并且很容易编码哈哈

  • 基于文件 - 在包含命令的某个目录中创建文件,让MainAu3删除它/它们
  • 注册表 - 可能比文件慢
  • 隐藏窗口 - 通过设置窗口文本(我知道!)比文件更快地进行通信?
  • 隐藏窗口 - SendMessage呃,太难编码
  • DDE - 不要让我开始

决策点

我需要与正在运行的MainAu3进行通信,因为原因。真正的问题是是否将关键钩机制嵌入到MainAu3实例中。

我想要的是AutoIt是否有一个可靠的机制,用于特定于应用程序的关键钩,如AutoHotKeys #IfWinActive

如果我嵌入,我讨厌设置和取消设置HotKeySet()的选项,以及轮询_IsPressed()。然后,通过AutoHotKey的外部键钩也很痛苦。

我想我会首先尝试使用HotKeySet()进行嵌入,然后看看它是如何起作用的。

有什么建议吗?

注意 "通信及#34;是单向的 - 我只需要发送命令。

1 个答案:

答案 0 :(得分:1)

如果您尝试控制的GUI是您自己的GUI:

如果您想要非系统范围的热键,则应使用

  

GUISetAccelerators(加速器[,winhandle])

GUISetAccelerators

Sets the accelerator table to be used in a GUI window.

参数

accelerators    A 2 dimensional array holding the accelerator table (See remarks).
winhandle   [optional] Windows handle as returned by GUICreate() (default is the previously used window).

说明

The array passed to this function contains the hotkey and the control ID of the accelerator. The array must be defined as Local/Global $aArray[n][2] - where n is the number of accelerator keys to set:

    $aArray[0][0] = Hotkey (in HotKeySet() format) of 1st accelerator
    $aArray[0][1] = Control ID of the 1st accelerator, as returned by GUICtrlCreate...
    $aArray[1][0] = Hotkey of 2nd accelerator
    $aArray[1][1] = Control ID of the 2nd accelerator
    ...
    $aArray[n][0] = Hotkey of nth accelerator
    $aArray[n][1] = Control ID of the nth accelerator

Passing this function a non-array will unset all accelerators for the given winhandle.

示例:

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>

Example()

Func Example()
    GUICreate("Custom MsgBox", 225, 80)

    GUICtrlCreateLabel("Please select a button.", 10, 10)
    Local $idYes = GUICtrlCreateButton("Yes", 10, 50, 65, 25)
    Local $idNo = GUICtrlCreateButton("No", 80, 50, 65, 25)
    Local $idExit = GUICtrlCreateButton("Exit", 150, 50, 65, 25)

    ; Set GUIAccelerators for the button controlIDs, these being Ctrl + y and Ctrl + n
    Local $aAccelKeys[2][2] = [["^y", $idYes],["^n", $idNo]]
    GUISetAccelerators($aAccelKeys)

    GUISetState(@SW_SHOW) ; Display the GUI.

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                MsgBox($MB_SYSTEMMODAL, "You selected", "Close")
                ExitLoop

            Case $idYes
                MsgBox($MB_SYSTEMMODAL, "You selected", "Yes") ; Displays if the button was selected or the hotkey combination Ctrl + y was pressed.

            Case $idNo
                MsgBox($MB_SYSTEMMODAL, "You selected", "No") ; Displays if the button was selected or the hotkey combination Ctrl + n was pressed.

            Case $idExit
                MsgBox($MB_SYSTEMMODAL, "You selected", "Exit")
                ExitLoop

        EndSwitch
    WEnd
    GUIDelete() ; Delete the GUI.
EndFunc   ;==>Example

如果您正在控制外部GUI,那么可以尝试摆弄Any GUI以使其正常工作