
Frage
Ich möchte, dass AutoHotkey automatisch erkennt, wenn ein bestimmtes Popup-Dialogfeld angezeigt wird, und bestimmte Aktionen ausführt. Wie mache ich das?
Konkretes Beispiel
In meinem speziellen Fall möchte ich, dass AutoHotkey dasInhaltsverzeichnis aktualisierenDialogfeld, das Word anzeigt, wenn ich das Inhaltsverzeichnis aktualisieren möchte.
Dies ist der Workflow:
Ich aktualisiere die Titel in meinem Word-Dokument
Ich drücke Ctrl+, Aum das gesamte Dokument auszuwählen
Ich drücke F9, um alle Felder zu aktualisieren
Dieser lästige modale Dialog erscheint (der sich laut meinen Google-Suchen nicht wegkonfigurieren lässt)
Jetzt muss ich drücken, Arrow downum auszuwählenGesamte Tabelle aktualisierengefolgt von Enterder TasteOKund fortsetzen
Ich möchte, dass AutoHotkey den Befehl Arrow down, automatisch ausgibt Enter, da ich den oben beschriebenen Arbeitsablauf ein Dutzend Mal am Tag ausführe.
Da ich den Workflow initiiere, könnte ich natürlich einfach ein AutoHotkey-Skript schreiben, das die ganze Sache für mich erledigt, beginnend mit Ctrl+ A, wie folgt:
#IfWinActive ahk_class OpusApp
F9::
Send, ^a
Send, {F9}
Sleep, 200
Send, {Down}
Send, {Enter}
return
Das obige Beispiel dient jedoch nur zur Veranschaulichung. Es gibt Fälle, in denen Popup-Dialoge zufällig angezeigt werden und ich möchte, dass AutoHotkey je nach Titel des Popup-Dialogs eine Aktion ausführt.
Meine bisherigen Recherchen
- Einige Internetquellen empfehlen die Verwendung einer AutoHotkey-Schleifedas endlos wiederholt wird und beispielsweise jede Sekunde prüft, ob ein Fenster mit einem bestimmten Titel existiert und es dann schließt. Aber ich finde, das ist eine Verschwendung von CPU-Ressourcen
- Einige andere Internetquellen erwähnen eineMuschelhakenzusammen mit einem Code-Schnipsel, und ich denke, das ist die richtige Möglichkeit, aber ich verstehe den Code-Schnipsel nicht; könnte jemand erklären, wie es funktioniert, und ein verständliches Beispiel geben, vorausgesetzt, dies wäre die Lösung?
Der folgende Codeausschnitt istvon hier kopiert.
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
}
ich sehe das
If (Title = "sun 4 - foxtrot - Remote Desktop Connection")
Teil. Was, was macht der ganze Rest?
Antwort1
Sie gehen in die Tiefe. Ein Programmmonitor für einen bestimmten Fensternamen belastet die Systemressourcen nicht sehr. Das ist wahrscheinlich der richtige Weg.
ShellMessage
könnte ein beliebiger Name sein, da es sich um die von aufgerufene Funktion handelt OnMessage
, die ausgelöst wird, wenn Ihr Skript eine Nachricht empfängt. Der Inhalt dieser Funktion sollte Ihr Code sein, um sicherzustellen, dass Sie sich im richtigen Fenster befinden und um dann die Befehle auszugeben, die Sie senden möchten. Ihre Funktion kann bis zu vier Parameter akzeptieren,wie in der Hilfedatei definiertfür OnMessage
.
Die DllCall
Zeilen sind der geheimnisvolle Teil, der in Windows eingebunden wird, um Nachrichten vom System abzurufen. Hier sollten Sie wissen, was Sie tun, wenn Sie sich mit dem Hooding in Windows beschäftigen wollen.
SetBatchLines, -1
und Process, Priority,, High
sagen Sie, dass Ihr Skript extrem wichtig ist und immer mit voller Geschwindigkeit laufen sollte und kein anderer Systemprozess es jemals verlangsamen sollte.
Gui +LastFound
und hWnd := WinExist()
ermitteln die eindeutige ID dieses Skripts während der Ausführung, damit es sich anschließend bei Windows registrieren kann DllCall
.
Antwort2
Für effizienten Code, der keine Abfragen durchführt und schneller reagiert, können Sie den Code hier anpassen:
Fügen Sie im Setup-Teil der Datei diese Anweisungen hinzu:
Update Table of Contents ahk_exe WINWORD.EXE B WordTOCupdate
Update Table of Figures ahk_exe WINWORD.EXE B WordTOCupdate
Stellen Sie sicher, dass sich in diesem Setup-Teil des Skripts Tabulatoren zwischen den Spalten befinden (und keine Leerzeichen, je nachdem, welchen Editor Sie verwenden). Der EXE-Name ist auch groß- und kleinschreibungsabhängig, da er RegEx-Matching verwendet, sofern Sie ihn nicht ändern.
Dieser Code wird dann in den Hauptteil des Skripts eingefügt ...
;-------------------------------------------------------
; Check for Microsoft Word Update Table of Contents
;-------------------------------------------------------
WordTOCupdate:
WinActivate ;Set Window to Be on top
SendInput !e{Enter}
return
Sie können auch den von Ihnen geposteten Snippet verwenden. Es ist im Grunde dasselbe.
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}
}
}
Das !e sendet Alt+e, um die gesamte Tabelle zu aktualisieren.