# GUI Referenz - OnEvent Modus

Anstatt die GUI ständig abzufragen, um herauszufinden ob etwas passiert ist, lässt du im OnEvent Modus die GUI zeitweise dein Skript anhalten und eine vordefinierte Funktion aufrufen, um das Ereignis zu behandeln. Wenn zum Beispiel ein Nutzer auf Button1 klickt, hält die GUI dein Hauptskript an und ruft eine vorher von dir definierte Funktion auf, die für Button1 zuständig ist. Wenn diese Funktion abgearbeitet ist, wird das Hauptskript fortgesetzt. Dieser Modus ist ähnlich wie die Visual Basic Formular-Methode.

Während die GUI ausgeführt wird, kann dein Hauptskript jede normale Skriptaufgabe ausführen, aber um das Beispiel möglichst einfach zu machen, lassen wir das Hauptskript einfach eine endlose While-Schleife ausführen.

Der voreingestellte Modus ist der MessageLoop Modus, deshalb müssen wir vor dem Benutzen des OnEvent Modus Opt("GUIOnEventMode", 1) verwenden.

## Grundlegendes OnEvent Format

Der allgemeine OnEvent Code sieht so aus:

While 1
Sleep(1000) ; Häng einfach rum
WEnd
Func Event1()
; Code zur Ereignis-Behandlung kommt hier hin
EndFunc
Func Event2()
; Code zur Ereignis-Behandlung kommt hier hin
EndFunc

## GUI Ereignisse

Im OnEvent Modus produziert deine GUI die folgenden "Ereignisse":

- Control-Ereignis
- System-Ereignis

Beide Ereignistypen rufen eine nutzerdefinierte Funktion auf, wenn eine für die GUI definiert wurde (GUISetOnEvent) oder wenn sie für ein Control (Steuerelement) definiert wurde (GUICtrlSetOnEvent). Wenn keine Funktion für ein Ereignis definiert wurde, dann wird dieses Ereignis einfach ignoriert. Innerhalb dieser aufgerufenen Funktion werden verschiedene Makros als Werte verwendet um die Ereignisbehandlung zu vereinfachen.

Makro | Details
@GUI_CTRLID | Die Control-ID des Steuerelements, das die Nachricht gesendet hat ODER die System-Ereignis-ID
@GUI_WINHANDLE | Der Handle der GUI, die die Nachricht gesendet hat
@GUI_CTRLHANDLE | Der Handle des Controls, das die Nachricht gesendet hat (falls anwendbar)

Beachte: Es ist völlig legal, die gleiche Funktion für mehrere Ereignisse zu verwenden; alles, was du in diesen Fällen tun musst, ist das @GUI_CTRLID Makro zu verwenden. Zum Beispiel könntest du alle System-Ereignisse der gleichen Funktion zuordnen.

Control-Ereignis

Wenn ein Steuerelement angeklickt wird oder sich verändert wird ein Control-Event gesendet. Das Ereignis wird an die Funktion gesendet, die mit GUICtrlSetOnEvent definiert wurde. Innerhalb der nutzerdefinierten Funktion wird @GUI_CTRLID auf die Control-ID gesetzt, die man beim anlegen des Steuerelements mit GUICtrlCreate... als Rückgabewert erhalten hat.

System-Ereignis

System-Ereignisse - wie das Schließen der GUI - werden auf ähnliche Weise wie Control-Ereignisse geschickt, aber der Ereignistyp wird durch @GUI_CTRLID definiert. Das Ereignis wird an die Funktion geschickt, die mit GUISetOnEvent definiert wurde. Die möglichen System-Ereignisse sind hier aufgelistet:

$GUI_EVENT_CLOSE
$GUI_EVENT_MINIMIZE
$GUI_EVENT_RESTORE
$GUI_EVENT_MAXIMIZE
$GUI_EVENT_PRIMARYDOWN
$GUI_EVENT_PRIMARYUP
$GUI_EVENT_SECONDARYDOWN
$GUI_EVENT_SECONDARYUP
$GUI_EVENT_MOUSEMOVE

## Beispiel-GUI

Auf der Hauptseite der GUI Referenz haben wir mit einem einfachen "Hallo Welt!" Beispiel angefangen, das so aussah:

#include <GUIConstants.au3>
GUICreate("Hallo Welt", 200, 100)
GUICtrlCreateLabel("Hallo Welt! Wie geht's?", 30, 10)
GUICtrlCreateButton("OK", 70, 50, 60)
GUISetState(@SW_SHOW)
Sleep(2000)

Jetzt vervollständigen wir den Code mit OnEvents und einigen der oben beschriebenen Ereignis-Nachrichten.

#include <GUIConstants.au3>
Opt("GUIOnEventMode", 1) ; Wechsle in den OnEvent Modus
$mainwindow = GUICreate("Hallo Welt", 200, 100)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
GUICtrlCreateLabel("Hallo Welt! Wie geht's?", 30, 10)
$okbutton = GUICtrlCreateButton("OK", 70, 50, 60)
GUICtrlSetOnEvent($okbutton, "OKButton")
GUISetState(@SW_SHOW)
While 1
Sleep(1000) ; Häng rum
WEnd
Func OKButton()
;Beachte: an diesem Punkt wäre @GUI_CTRLID gleich $okbutton,
;und @GUI_WINHANDLE wäre gleich $mainwindow
MsgBox(0, "GUI Event", "Du hast auf OK geklickt!")
EndFunc
Func CLOSEClicked()
;Beachte: an diesem Punkt wäre @GUI_CTRLID gleich $GUI_EVENT_CLOSE,
;und @GUI_WINHANDLE wäre gleich $mainwindow
MsgBox(0, "GUI Event", "Du hast auf CLOSE geklickt! Programm wird beendet...")
Exit
EndFunc

So einfach ist es. Offensichtlich wird es umso komplizierter, je mehr Fenster und Steuerelemente du anlegst, aber das Beispiel zeigt dir die Grundlagen.

## Fortgeschrittene Operationen und mehrere Fenster

Control-IDs sind eindeutig, auch wenn du mehrere Fenster hast, aber wie gehen wir mit mehreren Fenstern um?

Hier ist ein ähnliches Beispiel wie das oben, aber mit einem weiteren "dummy"-Fenster.

#include <GUIConstants.au3>
Opt("GUIOnEventMode", 1) ; Wechsle in den OnEvent Modus
$mainwindow = GUICreate("Hallo Welt", 200, 100)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
GUICtrlCreateLabel("Hallo Welt! Wie geht's?", 30, 10)
$okbutton = GUICtrlCreateButton("OK", 70, 50, 60)
GUICtrlSetOnEvent($okbutton, "OKButton")
$dummywindow = GUICreate("Dummy-Fenster zum Testen ", 200, 100)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
GUISwitch($mainwindow)
GUISetState(@SW_SHOW)
While 1
Sleep(1000) ; Häng rum
WEnd
Func OKButton()
;Beachte: an diesem Punkt wäre @GUI_CTRLID gleich $okbutton
MsgBox(0, "GUI Event", "Du hast auf OK geklickt!")
EndFunc
Func CLOSEClicked()
;Beachte: an diesem Punkt wäre @GUI_CTRLID gleich $GUI_EVENT_CLOSE,
;@GUI_WINHANDLE ist entweder gleich $mainwindow oder $dummywindow
If @GUI_WINHANDLE = $mainwindow Then
MsgBox(0, "GUI Event", "Du hast auf CLOSE im Hauptfenster geklickt! Programm wird beednet...")
Exit
EndIf
EndFunc

Die erste wesentliche Änderung ist der Aufruf der GUISwitch Funktion - wenn ein neues Fenster angelegt wird, wird es zum "default"-Fenster für zukünftige GUI-Operationen (einschließlich dem Anlegen von Steuerelementen). In unserem Fall wollen wir mit dem Hauptfenster "Hallo Welt" arbeiten, nicht mit dem Testfenster, deshalb schalten wir um ("switch". ). Einige GUI-Funktionen erlauben dir, den Fenster-Handle im Funktionsaufruf selbst zu verwenden - diese Funktionen werden automatisch umschalten. In unserem Beispiel hätten wir das so machen können:

GUISetState(@SW_SHOW, $mainwindow)

Beachte auch, dass wir die gleiche OnEvent-Funktion benutzt haben, um den "close" Button für beide Fenster zu behandeln und wir dann @GUI_WINHANDLE verwendet haben um zu bestimmen, welches Fenster die Nachricht gesendet hat - dann schließen wir die GUI nur, wenn der close-Button angeklickt wurde und die Nachricht vom Hauptfenster kam. Du kannst genausogut für jedes Fenster eine eigene Funktion verwenden, wenn du das willst.