用 AutoHotkey 實現【同一按鍵】在任意界面執行【默認功能】


AutoHotkey 對熱鍵的控制非常強大。可以通過窗口的以下信息綜合起來作為條件判斷

  • class
  • 標題
  • 程序名
  • 控件信息(當前激活控件,當前鼠標所在控件,控件狀態,控件值)

正因為有如此強大的判斷條件,就可以輕松設計一個(或多個)通用熱鍵(我用 F4)來針對各種界面的【默認功能】實現一鍵完成。

首先根據程序名分類

為大部分【主流程序】建個單獨的ahk文件(比如微信用 WeChat.ahk)

並用#HotIf WinActive("ahk_exe WeChat.exe")來定義動態熱鍵條件(優先級高)

這樣后續定義的熱鍵只會在微信生效(其他應用的熱鍵也用此法定義)

以下用 微信 舉例

  • 在程序里,可能需要根據不同的子窗口做相應的事
    • 微信的主界面 class = WeChatMainWndForPC
    • 轉發界面 class = SelectContactWnd
      轉發
    • 設置界面 class = SettingWnd
      image
    • 查看聊天記錄界面 class = FileManagerWnd(還可定義針對不同人的聊天記錄,自動設置默認要查找的內容)
      image
    • 另存為界面 class = #32770(大部分的保存對話框都是這個類名,由於有通用性,放到后面通用功能內)
  • 如果不匹配,則調用下方定義的【通用函數

非主流程序

其他通用功能,就不需要單獨建文件了,直接由自定義的【通用函數】(如general_smartDo())判斷執行

步驟
  • 程序名(由於程序名可能會帶 x64 或【空格】等內容,所以需要做下處理)
    exeName := StrReplace(RegExReplace(WinGetProcessName("A"), "i)_?(x?(64))?(\.\w+)?$"), " ", "_")

    定義各【程序名】的 map 列表,如果包含 exeName 則執行相應的函數(以下都是用此思想判斷)

  • class(獲取方法cls := WinGetClass("A"))
    上面提及的通用#32770保存對話框,我的主需求就是一鍵保存到桌面,就是在這里定義功能
  • 標題(獲取方法tt := WinGetTitle("A")) 其他原理同上
  • 控件等其他方式
  • 確定沒定義功能,則模擬發送F4熱鍵執行原生功能send("{F4}")

示例代碼如下,主要看思路結構

#HotIf WinActive("ahk_exe WeChat.exe") ;指定微信界面的熱鍵
F4::wechat_smartDo() ;在微信界面,則執行此函數(如果函數里都不匹配,可考慮執行通用函數 general_smartDo)

#HotIf WinActive("ahk_exe Excel.exe") ;指定Excel界面的熱鍵
F4::excel_smartDo()

#HotIf ;結束特定界面熱鍵定義,以下是通用的熱鍵
F4::general_smartDo() ;通用功能定義

;微信各界面的默認功能
wechat_smartDo(*) {
    if WinActive("ahk_class SelectContactWnd") {
        msgbox("【轉發】界面的自動化處理")
    } else if WinActive("ahk_class ImagePreviewWnd") { ;圖片查看
        WinGetPos(&winX, &winY, &w, &h)
        ControlClick(format("X{1} Y{2}", w//2+14, h-33)) ;圖片旋轉90度
    } else if WinActive("ahk_class SettingWnd") { ;設置界面
        msgbox("【設置】界面的自動化處理")
    } else ;NOTE 如果微信里沒定義,可考慮執行通用的功能
        general_smartDo()
}

excel_smartDo(*) {
    titleA := WinGetTitle("A")
    if WinActive("ahk_class NetUIHWND1") { ;打印頁面
        msgbox("空白打印頁如何解決?")
    } else if WinActive("排序") {
        t := ControlGetText("REComboBox20W3")
        if (t = "升序")
            ControlChooseIndex(2, "REComboBox20W3")
        else ;選升序
            ControlChooseIndex(1, "REComboBox20W3")
    } else {
        general_smartDo()
    }
}

;通用的功能定義模板
general_smartDo(*) {
    WinActive("A")
    ;程序名由於不規則,建議刪除 x64等文字,並把空格替換成_
    exeName := StrReplace(RegExReplace(WinGetProcessName(), "i)_?(x?(64))?(\.\w+)?$"), A_Space, "_")
    cls := WinGetClass()
    tt := WinGetTitle()
    ;exeName
    objExe := map(
        "rundll32",(p*)=>exe_rundll32(),
    )
    if objExe.has(exeName) {
        objExe[exeName].call()
        return
    }
    ;class
    objClass := map(
        "#32770" , (p*)=>class_32770(),
        "TMainFormFontCreator" , (p*)=>class_TMainFormFontCreator(),
    )
    if objClass.has(cls) {
        objClass[cls].call()
        return
    }
    exe_rundll32() {
        if WinActive("Internet 屬性") {
            ControlChooseIndex(5, "SysTabControl321")
            send("{alt down}l{alt up}")
        }
    }
    class_32770() {
        ;先判斷保存對話框的數據類型
        MouseGetPos(&x, &y, &hwnd, &ctlName)
        if instr(ctlName, "ComboBox") {
            hCtl := ControlGetHwnd(ctlName)
            if (UIA.ElementFromHandle(hCtl).GetCurrentPropertyValue("LegacyIAccessibleState") == 1049092) { ;1049604
                _ComboBox(ctlName).selectByText()
                return
            } else {
                tooltip("未擴展")
                SetTimer(tooltip, -1000)
            }
        }
        WinActive("A")
        sText := WinGetText()
        if instr(sText, "MSVCP120.dll") { ;由於找不到 MSVCP120.dll,無法繼續執行代碼。重新安裝程序可能會解決此問題。
            WinClose
            msgbox(sText)
        }
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM