====== Vega — Ereignisse und ihre Handler ======
Ein Handler ist in Vega eine **freie Funktion**, deren Signatur zum Ereignistyp passt. Zugewiesen wird sie wie ein Wert: ''b.OnClick := OnKlick;'' — ohne Klammern, denn zugewiesen wird die Funktion, nicht ihr Ergebnis.
Ein nicht gesetzter Handler ist ''0''. Vega prüft das vor jedem Aufruf; ein Ereignis ohne Handler passiert einfach nicht.
→ [[lyx_-_programmiersprache:vega:guides:erste-anwendung|Erste Anwendung]] · [[lyx_-_programmiersprache:vega:guides:eigenschaften|Eigenschaften]] · [[lyx_-_programmiersprache:vega:guides:komponenten|Komponenten]]
----
===== Die Handler-Typen =====
^ Typ ^ Signatur ^ Verwendet von ^
| ''TNotifyEvent'' | ''fn(sender: TControl): void'' | ''OnClick'', ''OnDblClick'', ''OnMouseEnter'', ''OnMouseLeave'', ''OnResize'', ''OnFocusIn'', ''OnFocusOut'', ''OnChange'', ''OnSelect'' |
| ''TMouseEvent'' | ''fn(sender: TControl, x: int64, y: int64, button: int64): void'' | ''OnMouseDown'', ''OnMouseUp'', ''OnMouseMove'', ''OnContextPopup'' |
| ''TKeyEvent'' | ''fn(sender: TControl, key: int64, modifiers: int64): void'' | ''OnKeyDown'', ''OnKeyUp'' |
| ''TCharEvent'' | ''fn(sender: TControl, cp: int64): void'' | ''OnChar'' — das **Zeichen** (Unicode-Codepoint), nicht die Taste |
| ''TWheelEvent'' | ''fn(sender: TControl, delta: int64): void'' | ''OnMouseWheel'' — ''+1'' hoch, ''-1'' runter |
| ''TPaintEvent'' | ''fn(sender: TControl, canvas: TCanvas): void'' | ''OnPaint'' |
| ''TDragOverEvent'' | ''fn(sender, source: TControl, x, y: int64): bool'' | ''OnDragOver'' — Rückgabe ''true'' heißt „ich nehme es an" |
| ''TDragDropEvent'' | ''fn(sender, source: TControl, x, y: int64): void'' | ''OnDragDrop'' |
| ''TDragEndEvent'' | ''fn(sender, target: TControl, x, y: int64): void'' | ''OnEndDrag'' — ''target'' ist ''0'', wenn nirgends abgelegt wurde |
| ''TTimerEvent'' | ''fn(sender: TControl): void'' | ''TTimer.OnTimer'' |
Die Mauskoordinaten sind **relativ zum Control**, nicht zum Fenster.
----
===== Ereignisse des Formulars =====
^ Ereignis ^ Wann ^
| ''OnCreate'' | Einmal, nachdem das Fenster steht |
| ''OnShow'' / ''OnHide'' | Jedes Mal beim Erscheinen/Verschwinden |
| ''OnActivate'' / ''OnDeactivate'' | Fenster bekommt/verliert den Fokus |
| ''OnClose'' | Vor dem Schließen — setzt der Handler ''f.CancelClose := true'', bleibt das Fenster offen („Wirklich beenden?") |
| ''OnDestroy'' | Beim Schließen, nach ''OnClose'' |
| ''OnResize'' | Größenänderung — hier gehören ''ApplyLayout()'' verschachtelter Container und die Menübreite hinein |
Für Tastenkürzel, die überall gelten sollen: ''f.KeyPreview := true'' und ''f.OnKeyDownForm'' — dann sieht das Formular die Taste **vor** dem fokussierten Element.
----
===== Beispiel =====
unit Main;
import std.io;
import Vega.Types;
import Vega.Events;
import Vega.Canvas;
import Vega.Theme;
import Vega.Control;
import Vega.Font;
import Vega.Strings;
import Vega.Lists;
import Vega.Style;
import Vega.StdCtrls;
import Vega.Edits;
import Vega.Backend;
import Vega.BackendAuto;
import Vega.Forms;
var g_app: TApplication;
var g_status: TLabel;
var g_feld: TEdit;
// TNotifyEvent: fn(sender: TControl): void
fn OnKlick(sender: TControl): void {
g_status.SetCaption("Klick auf: ");
var b: TButton := sender as TButton;
g_status.SetCaption(StrConcat("Klick auf: ", b.Caption));
}
// TMouseEvent: fn(sender, x, y, button): void — Koordinaten sind
// relativ zum Control, nicht zum Fenster.
fn OnMaus(sender: TControl, x: int64, y: int64, button: int64): void {
g_status.SetCaption(StrConcat(StrConcat("Maus ", IntToStr(x)), StrConcat("/", IntToStr(y))));
}
// TKeyEvent: fn(sender, key, modifiers): void
fn OnTaste(sender: TControl, key: int64, modifiers: int64): void {
if (key == KEY_ESCAPE) { g_app.Terminate(); }
if ((modifiers & MOD_CTRL) != 0 && key == KEY_RETURN) {
g_status.SetCaption("Strg+Enter");
}
}
// TNotifyEvent am Eingabefeld: der Sender ist das Feld selbst
fn OnAenderung(sender: TControl): void {
var e: TEdit := sender as TEdit;
g_status.SetCaption(e.GetText());
}
fn main(): int64 {
g_app := new TApplication(NewPlatformBackend());
if (!g_app.Ready) { PrintLn("Kein Fenstersystem erreichbar."); return 1; }
var f: TForm := new TForm(400, 220, "Ereignisse");
f.OnKeyDown := OnTaste;
g_status := new TLabel("bereit");
g_status.SetBounds(12, 12, 360, 18);
g_status.SetParent(f);
g_feld := new TEdit("tippen…");
g_feld.SetBounds(12, 40, 240, 24);
g_feld.OnChange := OnAenderung;
g_feld.SetParent(f);
var b: TButton := new TButton("Drueck mich");
b.SetBounds(12, 80, 140, 28);
b.OnClick := OnKlick;
b.OnMouseMove := OnMaus;
b.SetParent(f);
if (!g_app.ShowForm(f)) { return 2; }
g_app.Run();
g_app.Shutdown();
return 0;
}
Nachgemessen mit ''lyxc 1.1.3I'': übersetzt fehlerfrei (''lyxc events.lyx -I . -I platform/linux -o events'').
----
===== Der sender =====
Jeder Handler bekommt das auslösende Element als [[lyx_-_programmiersprache:vega:controls:tcontrol|TControl]]. Wer mehr braucht, castet:
fn OnAenderung(sender: TControl): void {
var e: TEdit := sender as TEdit;
g_status.SetCaption(e.GetText());
}
Damit lässt sich **ein** Handler an mehrere Elemente hängen; ''sender.Tag'' oder ''sender.Name'' unterscheidet sie dann. Das spart die Sorte Code, die sich sonst zwanzigmal wiederholt.
----
===== Tasten und Modifikatoren =====
Sondertasten kommen als ''KEY_*''-Konstanten aus ''Vega.Events'': ''KEY_RETURN'' (13), ''KEY_ESCAPE'' (27), ''KEY_TAB'' (9), ''KEY_LEFT'' (256), ''KEY_RIGHT'', ''KEY_UP'', ''KEY_DOWN'', ''KEY_HOME'', ''KEY_END'', ''KEY_DELETE'' (127), ''KEY_BACKSPACE'' (8).
Modifikatoren sind eine Bitmaske: ''MOD_SHIFT'' (1), ''MOD_CTRL'' (2), ''MOD_ALT'' (4), ''MOD_SUPER'' (8):
if ((modifiers & MOD_CTRL) != 0 && key == KEY_RETURN) { … }
Für getippten **Text** ist ''OnChar'' der richtige Weg — ''OnKeyDown'' unterscheidet ''A'' und ''a'' nicht.
----
===== Fallstricke =====
* **Kein Methodenzeiger.** Ein Handler ist eine freie Funktion; auf Elemente greift er über Modulvariablen zu.
* **Klammern weglassen.** ''b.OnClick := OnKlick;'' — mit ''OnKlick()'' würde die Funktion aufgerufen und ihr Ergebnis zugewiesen.
* **Nach eigenen Zustandsänderungen ''Invalidate()''.** Der Handler bekommt kein automatisches Neuzeichnen.
* **''OnMouseMove'' feuert oft.** Dort nichts rechnen, was teuer ist; nur merken und im ''Paint'' verwenden.
Letzte Aktualisierung: 2026-08-19 — Handler-Typen gegen ''Vega/Control.lyx'' und ''Vega/Forms.lyx'' abgeglichen, Beispiel mit ''lyxc 1.1.3I'' übersetzt.