====== 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.