
問題
我希望 AutoHotkey 能夠自動偵測何時出現某個彈出對話框並採取某些操作。我怎麼做?
具體例子
在我的特殊情況下,我希望 AutoHotkey 關閉更新目錄當我想要更新目錄時,Word 將顯示對話框。
這是工作流程:
我更新了 Word 文件中的標題
我按Ctrl+A選擇整個文檔
我按F9更新所有字段
現在,我需要Arrow down按選擇更新整個表然後Enter按好的並繼續
我希望 AutoHotkey 自動發出Arrow down,Enter命令,因為我每天會執行十幾次上述工作流程。
當然,因為我啟動了工作流程,所以我可以編寫一個 AutoHotkey 腳本,該腳本以Ctrl+開頭為我完成所有工作A,如下所示:
#IfWinActive ahk_class OpusApp
F9::
Send, ^a
Send, {F9}
Sleep, 200
Send, {Down}
Send, {Enter}
return
但是,上面的範例僅用於說明目的,在某些情況下,彈出對話方塊會隨機出現,我希望 AutoHotkey 根據彈出對話框的標題執行某些操作。
到目前為止我的研究
- 一些網路資源建議使用 AutoHotkey 循環它無限循環並檢查(例如每秒)是否存在具有特定標題的窗口,然後將其關閉。但我發現這浪費了CPU資源
- 其他一些網路來源提到貝殼鉤連同程式碼片段,我認為這是正確的方法,但我不理解程式碼片段;如果這是解決方案,誰能解釋它是如何工作的並給出一個可以理解的例子?
下面的程式碼片段是從這裡複製的。
SetBatchLines, -1
Process, Priority,, High
Gui +LastFound
hWnd := WinExist()
DllCall( "RegisterShellHookWindow", UInt,hWnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )
Return
ShellMessage( wParam,lParam ) {
If ( wParam = 32772 or WParam = 4) ; HSHELL_WINDOWACTIVATED := 4 or 32772
WinGetActiveTitle, Title
If ( Title = "sun 4 - foxtrot - Remote Desktop Connection" )
SetCapsLockState, on
else SetCapsLockState, off
}
我看到
If (Title = "sun 4 - foxtrot - Remote Desktop Connection")
部分。剩下的全部做什麼?
答案1
你正在深入。為給定的視窗名稱設定一個程式監視器不會對系統資源造成太大的負擔。這可能就是要走的路。
ShellMessage
可以是您選擇的任何名稱,因為它是 呼叫的函數OnMessage
,這是當您的腳本收到訊息時觸發的函數。該函數的內容應該是您的程式碼,以確保您位於正確的視窗中,然後發出您想要發送的命令。您的函數最多可以接受四個參數,依照說明文件中的定義為了OnMessage
。
這些DllCall
線路是與 Windows 相關聯以從系統取得訊息的神秘部分。如果您要對 Windows 進行屏蔽,您應該知道自己在做什麼。
SetBatchLines, -1
並Process, Priority,, High
說您的腳本非常重要,應該始終全速運行,並且任何其他系統進程都不應該減慢它的速度。
Gui +LastFound
並hWnd := WinExist()
在運行時查找該腳本的唯一ID,以便後續可以向Windows 註冊DllCall
。
答案2
對於不輪詢且響應速度更快的高效代碼,您可以在此處調整代碼:
在文件的設定部分中加入以下語句:
Update Table of Contents ahk_exe WINWORD.EXE B WordTOCupdate
Update Table of Figures ahk_exe WINWORD.EXE B WordTOCupdate
確保腳本的此設定部分中的列之間有製表符(而不是空格,取決於您使用的編輯器)。 exe 名稱也區分大小寫,因為它使用正規表示式匹配,除非您更改它。
然後這段程式碼會出現在腳本的主體中...
;-------------------------------------------------------
; Check for Microsoft Word Update Table of Contents
;-------------------------------------------------------
WordTOCupdate:
WinActivate ;Set Window to Be on top
SendInput !e{Enter}
return
您也可以使用您發布的程式碼片段...基本上是同一件事。
Gui +LastFound
hWnd := WinExist()
DllCall( "RegisterShellHookWindow", UInt,hWnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )
Return
ShellMessage( wParam,lParam ) {
If ( wParam = 32772 or WParam = 4) ; HSHELL_WINDOWACTIVATED := 4 or 32772
WinGetActiveTitle, Title
If (Title="Update Table of Contents" )
{
SendInput !e{Enter}
}
}
!e 發送 Alt+e 來更新整個表。