Registriert eine Subroutine, die automatisch und wiederholt in einem bestimmten Zeitintervall gestartet wird.
SetTimer , Label, PeriodeOnOffDelete, Priorität
Name eines Labels, Hotkey-Labels oder Hotstring-Labels, zu dem gesprungen werden soll, um alle Befehle unterhalb von Label bis zu einem Return oder Exit auszuführen. Label kann, wie die meisten Parameter von anderen Befehlen auch, eine Variablenreferenz wie %MeinLabel% sein, um den Inhalt der Variable als Ziel zu verwenden.
[v1.1.01+]: Wenn Label weggelassen wird, wird standardmäßig A_ThisLabel verwendet. Zum Beispiel kann SetTimer,, Off
innerhalb einer Timer-Subroutine verwendet werden, um den Timer zu deaktivieren, während SetTimer,, 1000
entweder die Periode des aktuellen Timers ändert oder einen neuen Timer mit dem Label der aktuell laufenden Subroutine erstellt. [v1.1.24+]: Wenn A_ThisLabel leer ist, aber der aktuelle Thread von einem Timer gestartet wurde, wird dieser Timer verwendet. Dies ist besonders nützlich für Timer, die Funktionen oder Funktionsobjekte starten müssen.
[v1.1.20+]: Dieser Parameter kann auch der Name einer Funktion ohne Pflichtparameter sein, wenn kein Label mit diesem Namen existiert, wie in Beispiel #4, oder eine einzelne Variablenreferenz mit einem Funktionsobjekt, wie in Beispiel #5. Andere Ausdrücke, die Objekte zurückgeben, werden zurzeit nicht unterstützt.
Hinweis: In [v1.1.24+] wird die Übergabe einer leeren Variable oder eines Ausdrucks, der einen leeren Wert zurückgibt, als Fehler gewertet. Dieser Parameter muss entweder einen nicht-leeren Wert enthalten oder ganz weggelassen werden.
Wenn leer oder weggelassen und der Timer nicht existiert, wird er mit einer Periode von 250 erstellt. Wenn leer oder weggelassen und der Timer bereits existiert, wird er aktiviert und auf seine frühere Periode zurückgesetzt, sofern keine Priorität angegeben ist. Andernfalls geben Sie Folgendes an:
Periode: Erstellt oder aktualisiert einen Timer unter Verwendung des Absolutwertes dieses Parameters als ungefähre Zeit in Millisekunden, die ablaufen muss, bevor der Timer ausgeführt wird. Der Timer wird automatisch aktiviert und zurückgesetzt. Wenn Periode positiv ist, wiederholt sich der Timer automatisch, bis er im Skript explizit deaktiviert wird. [v1.0.46.16+]: Wenn Periode negativ ist, wird der Timer nur einmal ausgeführt. Zum Beispiel wird durch Angabe von -100 der Timer nach 100 ms einmal ausgeführt und dann deaktiviert, als wäre SetTimer, Label, Off
verwendet worden. [v1.1.24+]: Wenn Label ein via Skript erstelltes Objekt ist (also keine Funktion oder Label), wird der Timer automatisch gelöscht, nachdem die Timerfunktion ihren Wert zurückgegeben hat, es sei denn, der Timer wurde reaktiviert. Dadurch kann das Objekt freigegeben werden, wenn es vom Skript nicht mehr benötigt wird, was aber auch bedeutet, dass die Periode und Priorität des Timers verworfen werden.
Periode muss ein Integer sein, es sei denn, es wird eine Variable oder ein Ausdruck verwendet, dann werden alle Dezimalstellen ignoriert. Der Absolutwert darf nicht größer als 4294967295 ms (49,7 Tage) sein.
On: Reaktiviert einen zuvor deaktivierten Timer mit seiner früheren Periode. Wenn der Timer nicht existiert, wird er erstellt (mit einer Standardperiode von 250). Der Timer wird auch zurückgesetzt. Wenn der Timer existiert, aber zuvor auf den Nur-Einmal-Ausführen-Modus (siehe oben) gesetzt wurde, wird er auch dieses Mal nur einmal ausgeführt.
Off: Deaktiviert einen existierenden Timer.
Delete [v1.1.20+]: Deaktiviert und löscht einen existierenden Timer. Wenn der Timer mit einem Funktionsobjekt verbunden ist, wird das Objekt freigegeben. Die Deaktivierung allein führt nicht zur Freigabe des Objekts.
Wenn leer oder weggelassen, wird standardmäßig 0 verwendet. Andernfalls geben Sie einen Integer zwischen -2147483648 und 2147483647 (oder einen Ausdruck) an, um die Thread-Priorität des Timers zu bestimmen. Einzelheiten finden Sie unter Threads.
Um die Priorität eines existierenden Timers zu ändern, ohne ihn anderweitig zu beeinflussen, lassen Sie den Parameter vor diesem leer.
Timer sind nützlich, weil sie asynchron laufen, d.h. sie werden in einem bestimmten Intervall (Frequenz) ausgeführt, egal ob das Skript gerade auf ein Fenster wartet, ein Dialogfenster anzeigt oder mit einer anderen Aufgabe beschäftigt ist. Timer können u.a. verwendet werden, um eine Aktion während der Abwesenheit des Benutzers auszuführen (in Verbindung mit A_TimeIdle) oder um unerwünschte Fenster sofort wieder zu schließen, wenn sie erscheinen.
Timer erzeugen nur die Illusion, als könne das Skript mehr als eine Aufgabe gleichzeitig ausführen. In Wirklichkeit werden zeitgesteuerte Subroutinen wie andere Threads behandelt: Sie können andere Threads, wie z.B. Hotkey-Subroutinen, unterbrechen oder von ihnen unterbrochen werden. Einzelheiten finden Sie unter Threads.
Jedes Mal, wenn ein Timer erstellt, reaktiviert oder mit einer neuen Periode aktualisiert wird, wird seine Subroutine nicht sofort ausgeführt; seine Periode muss zuerst ablaufen. Wenn die erste Ausführung des Timers sofort erfolgen soll, führen Sie seine Subroutine mit Gosub aus (dabei wird allerdings kein neuer Thread gestartet, wie es der Timer selbst tut, d.h. Einstellungen wie SendMode verwenden zunächst nicht ihre Standardwerte).
Zurücksetzen: Wenn SetTimer auf einen bereits existierenden Timer angewendet wird und der 2. Parameter eine Zahl oder das Wort ON ist (oder leer ist oder weggelassen wird), wird der Timer zurückgesetzt, d.h. seine Periode muss einmal komplett ablaufen, bevor seine Subroutine erneut starten kann.
Genauigkeit des Timers: Durch die Granularität (Ungenauigkeit) der Zeiterfassung im Betriebssystem wird Periode möglicherweise auf das nächstmögliche Vielfache von 10 oder 15.6 Millisekunden aufgerundet (abhängig vom Typ der installierten Hardware und Treiber). In Windows 2000/XP ist eine Periode von 1 bis 10 äquivalent zu 10 oder 15.6. Eine kürzere Verzögerung kann mit Loop+Sleep erreicht werden, wie bei DllCall+timeBeginPeriod+Sleep gezeigt.
Zuverlässigkeit: Es ist möglich, dass ein Timer nicht zum erwarteten Zeitpunkt ausgeführt wird, wenn die folgenden Bedingungen zutreffen:
Obwohl Timer auch laufen, wenn das Skript suspendiert ist, werden sie nicht ausgeführt, wenn Thread NoTimers für den aktuellen Thread wirksam ist oder wenn ein beliebiger Thread pausiert wird. Außerdem werden sie nicht ausgeführt, wenn der Benutzer durch eines der Menüs des Skripts navigiert (z.B. das Tray-Symbol-Menü oder eine Menüleiste).
Da Timer die laufende Skriptaktivität vorübergehend unterbrechen, sollten ihre Subroutinen kurz gehalten werden (so dass sie schnell zum Abschluss kommen), wenn eine lange Unterbrechung unerwünscht ist.
Sonstige Bemerkungen: Timer, die die ganze Zeit laufen, werden üblicherweise im automatischen Ausführungsbereich erstellt, während ein temporärer Timer sich oft durch seine eigene Subroutine selbst deaktiviert (siehe Beispiele weiter unten).
Jede via SetTimer gestartete Subroutine verwendet vorerst die Standardwerte von Einstellungen wie SendMode. Diese Standardwerte können im automatischen Ausführungsbereich geändert werden.
Wenn die Hotkey-Reaktionszeit von entscheidender Bedeutung ist (z.B. in Videospielen) und Timer im Skript enthalten sind, deren Subroutinen länger als 5 ms zum Ausführen benötigen, verwenden Sie den folgenden Befehl, um eine mögliche Verzögerung von 15 ms zu vermeiden. Eine solche Verzögerung würde sonst auftreten, wenn ein Hotkey genau dann gedrückt wird, wenn sich ein Timer-Thread in seiner unterbrechungsfreien Phase befindet:
Thread, Interrupt, 0 ; Macht alle Threads jederzeit unterbrechbar.
Wenn ein Timer deaktiviert wird, während seine Subroutine gerade läuft, wird diese Subroutine fertig ausgeführt.
KeyHistory zeigt an, wie viele Timer es gibt und wie viele gerade aktiv sind.
Um ein Skript dauerhaft laufen zu lassen - z.B. ein Skript, das nur Timer enthält - verwenden Sie #Persistent.
Gosub, Return, Threads, Thread (Befehl), Critical, IsLabel(), Menu, #Persistent
Schließt unerwünschte Fenster, sobald sie erscheinen.
#Persistent SetTimer, MailWarnungenSchließen, 250 return MailWarnungenSchließen: WinClose, Microsoft Outlook, Während der Kommunikation mit dem Server wurde das Zeitlimit überschritten WinClose, Microsoft Outlook, Es konnte keine Verbindung aufgebaut werden return
Wartet auf ein bestimmtes Fenster und alarmiert dann den Benutzer.
#Persistent SetTimer, Alarm1, 500 return Alarm1: if not WinExist("Videokonvertierung", "Prozess abgeschlossen") return ; Andernfalls: SetTimer, Alarm1, Off ; d.h. der Timer deaktiviert sich selbst. SplashTextOn, , , Die Videokonvertierung wurde abgeschlossen. Sleep, 3000 SplashTextOff return
Erkennt, ob ein Hotkey einmal, zweimal oder dreimal gedrückt wurde. Dadurch kann ein Hotkey eine andere Aktion ausführen, je nachdem, wie oft er gedrückt wurde.
#c:: if (winc_eingaben > 0) ; SetTimer bereits gestartet, also stattdessen den Tastendruck protokollieren. { winc_eingaben += 1 return } ; Andernfalls ist das der erste Tastendruck einer neuen Serie. Zählung wird ; auf 1 gesetzt und der Timer gestartet: winc_eingaben := 1 SetTimer, TasteWinC, -400 ; Auf weitere Eingaben innerhalb von 400 ms warten. return TasteWinC: if (winc_eingaben = 1) ; Die Taste wurde einmal gedrückt. { Run, m:\ ; Einen Ordner öffnen. } else if (winc_eingaben = 2) ; Die Taste wurde zweimal gedrückt. { Run, m:\multimedia ; Einen anderen Ordner öffnen. } else if (winc_eingaben > 2) { MsgBox, Drei oder mehr Klicks erkannt. } ; Egal welche obige Aktion ausgelöst wurde, Zählung zurücksetzen, ; um die nächste Serie von Tastendrücken vorzubereiten: winc_eingaben := 0 return
Ein einfacher Zähler. Verwendet eine Funktion als Timer-Subroutine.
#Persistent SetTimer, Tick, 1000 Tick() { static count := 0 ToolTip % count++ }
Ein komplexerer Zähler. Verwendet eine Methode als Timer-Subroutine.
counter := new SecondCounter counter.Start() Sleep 5000 counter.Stop() Sleep 2000 ; Eine Beispielklasse zum Zählen von Sekunden... class SecondCounter { __New() { this.interval := 1000 this.count := 0 ; Tick() hat einen impliziten Parameter "this", der eine Referenz auf ; das Objekt ist, daher müssen wir eine Funktion erstellen, die ; "this" und die aufzurufende Methode voneinander trennt: this.timer := ObjBindMethod(this, "Tick") } Start() { ; Bekannte Einschränkung: SetTimer benötigt eine reine Variablenreferenz. timer := this.timer SetTimer % timer, % this.interval ToolTip % "Zähler gestartet" } Stop() { ; Um den Timer zu deaktivieren, dasselbe Objekt erneut übergeben: timer := this.timer SetTimer % timer, Off ToolTip % "Zähler ist bei " this.count " gestoppt" } ; In diesem Beispiel ruft der Timer diese Methode auf: Tick() { ToolTip % ++this.count } }
Tipps zum obigen Beispiel:
this.timer := this.Tick.Bind(this)
verwenden. Wenn this.timer
aufgerufen wird, wird es eigentlich this.Tick.Call(this)
indirekt aufrufen (außer dass this.Tick
nicht neu evaluiert wird). ObjBindMethod() hingegen erzeugt ein Objekt, das this.Tick()
indirekt aufruft.this
direkt anstelle von this.timer
verwenden. Damit entfällt auch die Notwendigkeit der temporären Variable. Allerdings ist ObjBindMethod() nützlich, wenn das Objekt mehrere Methoden hat, die von verschiedenen Ereignisquellen aufgerufen werden sollen, z.B. Hotkeys, Menüpunkte, GUI-Steuerelemente, usw.timer
im obigen Beispiel).