Wie man Fenster manipuliert

Eines der einfachsten und nützlichsten Dinge, die Sie mit AutoHotkey tun können, ist das Erstellen von Tastaturkurzbefehlen (Hotkeys), die Fenster manipulieren. Ein Skript kann fast jedes Fenster aktivieren, schließen, minimieren, maximieren, wiederherstellen, verstecken, sichtbar machen oder verschieben. Dies geschieht durch Aufruf der entsprechenden Win-Funktion, wobei das Fenster über den Titel oder ein anderes Kriterium angegeben wird:

Run "notepad.exe"
WinWait "Unbenannt - Editor"
WinActivate "Unbenannt - Editor"
WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2, "Unbenannt - Editor"

Dieses Beispiel öffnet ein neues Notepad-Fenster und verschiebt es dann so, dass es einen Teil des primären Bildschirms ausfüllt (¼ seiner Breite und ½ seiner Höhe). Wie Sie es ausprobieren können, erfahren Sie unter Wie man Beispielcodes ausführt.

Es gibt viele Funktionen zum Manipulieren von Fenstern, allerdings werden wir nicht näher darauf eingehen, da sie recht einfach zu verstehen sind. Um zum Beispiel ein Fenster zu minimieren anstatt es zu aktivieren, ersetzen Sie WinActivate mit WinMinimize. Eine Liste der Funktionen, mit denen Fenster manipuliert oder Informationen abgerufen werden können, finden Sie unter Win-Funktionen.

Der größte Teil dieses Tutorials handelt davon, wie man das gewünschte Fenster identifiziert, da dies oft die meisten Schwierigkeiten bereitet. Das obige Beispiel weist gleich mehrere Probleme auf:

Wir werden diese Probleme Schritt für Schritt durchgehen, nachdem wir einige Grundlagen besprochen haben.

Tipp: AutoHotkey wird zusammen mit einem Skript namens Window Spy ausgeliefert, mit dem der Titel, die Klasse und der Prozessname eines Fensters bestätigt werden kann. Die Klasse und der Prozessname werden häufig verwendet, wenn ein Fenster nicht allein durch seinen Titel identifiziert werden kann. Sie finden Window Spy im Tray-Menü des Skripts oder im AutoHotkey Dash.

Titelübereinstimmung

Bei der Angabe eines Fensters über seinen Titel gibt es einige Dinge zu beachten:

Weitere Informationen finden Sie unter Übereinstimmungsverhalten.

Aktives Fenster

Um mit dem aktiven Fenster zu arbeiten, verwenden Sie den Buchstaben "A" anstelle des Fenstertitels. Das folgende Beispiel minimiert das aktive Fenster:

WinMinimize "A"

Zuletzt Gefundenes Fenster

Wenn WinWait, WinExist, WinActive, WinWaitActive oder WinWaitNotActive ein passendes Fenster findet, wird es zum zuletzt gefundenen Fenster. Bei den meisten Fensterfunktionen kann der Fenstertitel (und verwandte Parameter) weggelassen werden, um standardmäßig das zuletzt gefundene Fenster zu verwenden. Zum Beispiel:

Run "notepad.exe"
WinWait "Unbenannt - Editor"
WinActivate
WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2

Dadurch entfällt die wiederholte Angabe des Fenstertitels, was etwas Zeit spart, die Aktualisierung des Skripts erleichtert, wenn der Fenstertitel geändert werden muss, und ggf. die Lesbarkeit des Codes verbessert. Es erhöht die Zuverlässigkeit des Skripts, indem es sicherstellt, dass es jedes Mal mit demselben Fenster arbeitet, selbst bei mehreren gefundenen Fenstern oder wenn sich der Fenstertitel ändert, nachdem das Fenster "gefunden" wurde. Dies erhöht auch geringfügig die Effizienz der Skriptausführung.

Fensterklasse

Eine Fensterklasse ist eine Reihe von Attributen, die als Vorlage für die Erstellung eines Fensters verwendet wird. Oft steht der Name der Fensterklasse im Zusammenhang mit der Applikation oder dem Zweck des Fensters. Die Klasse eines Fensters ändert sich nie, solange das Fenster existiert, und ist daher ein guter Kandidat für die Identifizierung eines Fensters, wenn die Identifizierung über den Titel unpraktisch oder unmöglich ist.

Zum Beispiel können wir anstelle des Fenstertitels "Unbenannt - Editor" die Klasse des Fensters verwenden, die in diesem Fall immer "Notepad" ist, unabhängig von der Systemsprache:

Run "notepad.exe"
WinWait "ahk_class Notepad"
WinActivate
WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2

Um eine Fensterklasse von einem Titel zu unterscheiden, verwenden Sie das Wort "ahk_class" wie oben gezeigt. Um mehrere Kriterien zu kombinieren, listen Sie zuerst den Fenstertitel auf. Zum Beispiel: "Unbenannt ahk_class Notepad".

Siehe auch: ahk_class

Prozessname/-pfad

Um Fenster anhand des Prozesses, der sie erstellt hat, zu identifizieren, verwenden Sie das Wort "ahk_exe", gefolgt vom Namen oder Pfad des Prozesses. Zum Beispiel:

Run "notepad.exe"
WinWait "ahk_exe notepad.exe"
WinActivate
WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2

Siehe auch: ahk_exe

Prozess-ID (PID)

Jeder Prozess hat eine ID-Nummer, die bis zur Schließung des Prozesses eindeutig bleibt. Wir können diese Nummer verwenden, um unser Notepad-Beispiel zuverlässiger zu machen, indem wir sicherstellen, dass es alle Notepad-Fenster außer dem vom neuen Prozess erstellten Fenster ignoriert:

Run "notepad.exe",,, &notepad_pid
WinWait "ahk_pid " notepad_pid
WinActivate
WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2

Wir müssen drei aufeinanderfolgende Kommas verwenden; zwei davon dienen nur dazu, die ungenutzten Parameter ArbeitVerz und Optionen der Run-Funktion zu überspringen, da wir nur den vierten Parameter (AusgabeVarPID) benötigen.

Das Und-Zeichen (&) ist der Referenzoperator. Es wird verwendet, um die notepad_pid-Variable per Referenz an die Run-Funktion zu übergeben (d.h. um die Variable selbst anstelle ihres Wertes zu übergeben), was der Funktion ermöglicht, der Variable einen neuen Wert zuzuweisen. Anschließend dient notepad_pid als Platzhalter für die tatsächliche Prozess-ID.

Die Zeichenkette "ahk_pid " wird mit der Prozess-ID, die in der notepad_pid-Variable enthalten ist, verkettet, indem sie einfach nebeneinander geschrieben und durch Leerraumzeichen voneinander getrennt werden. Das Ergebnis ist eine Zeichenkette wie "ahk_pid 1040", wobei die Zahl nicht vorhersagbar ist.

Falls der neue Prozess mehrere Fenster erzeugt, können ein Fenstertitel und andere Kriterien kombiniert werden, indem sie durch Leerzeichen voneinander getrennt werden. Der Fenstertitel muss immer ganz vorne stehen. Zum Beispiel: "Unbenannt ahk_class Notepad ahk_pid " notepad_pid.

Siehe auch: ahk_pid

Fenster-ID (HWND)

Jedes Fenster hat eine ID-Nummer, die bis zur Zerstörung des Fensters eindeutig bleibt. In der Programmierung wird diese Nummer als "window handle" (Fensterhandle) oder HWND bezeichnet. Obwohl die Fenster-ID nicht so praktisch ist wie die Verwendung des zuletzt gefundenen Fensters, kann die Fenster-ID in eine Variable gespeichert werden, damit das Skript auf das Fenster per Namen Ihrer Wahl verweisen kann, auch wenn sich sein Titel ändert. Es kann immer nur ein zuletzt gefundenes Fenster geben, aber Sie können so viele Fenster-IDs verwenden, wie Sie sich Variablennamen ausdenken können (oder Sie können ein Array verwenden).

Eine Fenster-ID ist der Rückgabewert von WinWait, WinExist oder WinActive oder kann aus anderen Quellen stammen. Das Notepad-Beispiel kann so umgeschrieben werden, dass es einen Vorteil daraus zieht:

Run "notepad.exe"
notepad_id := WinWait("Unbenannt - Editor")
WinActivate notepad_id
WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2, notepad_id

Dies weist den Rückgabewert von WinWait der Variable "notepad_id" zu. Mit anderen Worten, wenn WinWait das Fenster findet, gibt es die ID des Fensters als Ergebnis zurück, und das Skript speichert dieses Ergebnis dann in die Variable. "notepad_id" ist nur ein Name, den ich mir für dieses Beispiel ausgedacht habe; Sie können einen beliebigen Variablennamen verwenden, der Ihnen sinnvoll erscheint (mit gewissen Einschränkungen).

Beachten Sie, dass ich den Fenstertitel in runden Klammern gesetzt habe, direkt hinter dem Funktionsnamen. Die runden Klammern können bei Funktionsaufrufanweisungen (Funktionsaufrufe ganz am Anfang der Zeile) weggelassen werden, aber dann kann der Rückgabewert der Funktion nicht abgerufen werden.

Das Skript kann die Variable notepad_id auch für spätere Zwecke wiederverwenden, z.B. zum Schließen, Reaktivieren oder Verschieben des Fensters.

Siehe auch: ahk_id

Zeitlimit

Standardmäßig wartet WinWait unendlich lang, bis ein passendes Fenster erscheint. Sie können feststellen, ob dies der Fall ist, indem Sie das Hauptfenster des Skripts über das Tray-Symbol öffnen (sofern Sie es nicht deaktiviert haben). Normalerweise wird das Fenster in der ListLines-Ansicht geöffnet. Wenn WinWait noch wartet, wird es ganz unten in der Zeilenliste angezeigt, gefolgt von den Sekunden seit Beginn der Wartezeit. Um die Sekunden zu aktualisieren, wählen Sie "Refresh" im View-Menü aus.

Versuchen Sie, das folgende Beispiel auszuführen und das Hauptfenster wie oben beschrieben zu öffnen:

WinWait "Unbenannt - Editr"  ; (absichtlicher Schreibfehler)

Wenn das Skript beim Warten auf ein Fenster "hängt", müssen Sie es normalerweise beenden oder neu laden, um es wieder zum Laufen zu bringen. Um zu verhindern, dass dies (wieder) passiert, können Sie den Zeitlimit-Parameter von WinWait verwenden. Das folgende Beispiel wartet maximal 5 Sekunden, bis das Fenster erscheint:

Run "notepad.exe",,, &notepad_pid
if WinWait("ahk_pid " notepad_pid,, 5)
{
    WinActivate
    WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2
}

Der Block unter der if-Anweisung wird nur ausgeführt, wenn WinWait ein passendes Fenster findet. Wenn es das Zeitlimit überschreitet, wird der Block übersprungen und die Ausführung nach der geschweiften Endklammer fortgesetzt (falls danach noch Code vorhanden ist).

Beachten Sie, dass die runden Klammern hinter "WinWait" notwendig sind, wenn wir das Ergebnis der Funktion in einem Ausdruck verwenden wollen (z.B. als Bedingung für eine if-Anweisung). Sie können sich den eigentlichen Funktionsaufruf als Ersatz für das Funktionsergebnis vorstellen. Wenn z.B. WinWait eine Übereinstimmung findet, bevor es das Zeitlimit überschreitet, ist das Ergebnis ungleich Null. if 1 würde den Block unterhalb der if-Anweisung ausführen, während if 0 ihn überspringen würde.

Eine andere Möglichkeit besteht darin, Return zu verwenden (bzw. abzubrechen), wenn das Zeitlimit überschritten wurde. Zum Beispiel:

Run "notepad.exe",,, &notepad_pid
if !WinWait("ahk_pid " notepad_pid,, 5)
    return
WinActivate
WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2

Das Ergebnis wird durch den Operator Logisches NICHT (! oder not) invertiert. Wenn WinWait das Zeitlimit überschreitet, gibt es 0 zurück. Das Ergebnis von !0 ist 1. Wenn WinWait das Zeitlimit überschreitet, führt die if-Anweisung return aus.

Das Ergebnis von WinWait ist eigentlich die ID des Fensters (wie oben beschrieben) oder Null, wenn das Zeitlimit überschritten wurde. Wenn Sie das Fenster auch über seine ID ansprechen wollen, können Sie das Ergebnis einer Variable zuweisen, anstatt es direkt in der if-Anweisung zu verwenden:

Run "notepad.exe",,, &notepad_pid
notepad_id := WinWait("ahk_pid " notepad_pid,, 5)
if notepad_id
{
    WinActivate notepad_id
    WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2, notepad_id
}

Um die wiederholte Angabe des Variablennamens zu vermeiden, können Sie das Ergebnis einer Variable zuweisen und gleichzeitig prüfen, ob es ungleich Null (true) ist:

Run "notepad.exe",,, &notepad_pid
if notepad_id := WinWait("ahk_pid " notepad_pid,, 2)
{
    WinActivate notepad_id
    WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2, notepad_id
}

Achten Sie in diesem Fall darauf, := (Zuweisung) nicht mit = oder == (Vergleich) zu verwechseln. Zum Beispiel weist if meinevar := 0 einen neuen Wert zu und liefert jedes Mal dasselbe Ergebnis (false), während if meinevar = 0 einen zuvor zugewiesenen Wert mit 0 vergleicht.

Ausdrücke (Mathematik usw.)

Wenn Sie ein Fenster verschieben wollen, empfiehlt es sich, das Fenster relativ zu seiner vorherigen Position oder Größe zu verschieben, die Sie mit der WinGetPos-Funktion abrufen können. Zum Beispiel können Sie die folgenden Hotkeys verwenden, um das aktive Fenster um 10 Pixel in jede Richtung zu verschieben, indem Sie die rechte Strg-Taste gedrückt halten und die Pfeiltasten drücken:

>^Left::    VerschiebeAktivesFensterUm(-10,   0)
>^Right::   VerschiebeAktivesFensterUm(+10,   0)
>^Up::      VerschiebeAktivesFensterUm(  0, -10)
>^Down::    VerschiebeAktivesFensterUm(  0, +10)

VerschiebeAktivesFensterUm(x, y) {
    WinExist "A"  ; Macht das aktive Fenster zum Zuletzt Gefundenen Fenster  
    WinGetPos &aktuell_x, &aktuell_y
    WinMove aktuell_x + x, aktuell_y + y
}

Das Beispiel definiert eine Funktion, um eine mehrfache Wiederholung von Code zu vermeiden. x und y werden zu Platzhaltern für die beiden Zahlen, die in jedem Hotkey angegeben sind. WinGetPos speichert die aktuelle Position in aktuell_x und aktuell_y, die wir dann mit x und y addieren.

Einfache Ausdrücke wie diese sollten Ihnen bekannt vorkommen. Weitere Informationen finden Sie unter Ausdrücke; beachten Sie aber, dass dort vieles steht, was Sie vermutlich nicht sofort lernen müssen.