AutoHotkey 對熱鍵的控制非常強大。可以通過窗口的以下信息綜合起來作為條件判斷
- class
- 標題
- 程序名
- 控件信息(當前激活控件,當前鼠標所在控件,控件狀態,控件值)
正因為有如此強大的判斷條件,就可以輕松設計一個(或多個)通用熱鍵(我用 F4
)來針對各種界面的【默認功能】實現一鍵完成。
首先根據程序名分類
為大部分【主流程序】建個單獨的ahk文件(比如微信用 WeChat.ahk
)
並用#HotIf WinActive("ahk_exe WeChat.exe")
來定義動態熱鍵條件(優先級高)
這樣后續定義的熱鍵只會在微信生效(其他應用的熱鍵也用此法定義)
以下用 微信 舉例
- 在程序里,可能需要根據不同的子窗口做相應的事
- 微信的主界面 class =
WeChatMainWndForPC
- 轉發界面 class =
SelectContactWnd
- 設置界面 class =
SettingWnd
- 查看聊天記錄界面 class =
FileManagerWnd
(還可定義針對不同人的聊天記錄,自動設置默認要查找的內容)
- 另存為界面 class = #32770(大部分的保存對話框都是這個類名,由於有通用性,放到后面通用功能內)
- 微信的主界面 class =
- 如果不匹配,則調用下方定義的【通用函數】
非主流程序
其他通用功能,就不需要單獨建文件了,直接由自定義的【通用函數】(如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)
}
}
}