Eine Anwendung ist nicht auf ein Fenster festgelegt. TApplication verwaltet beliebig viele; das erste gezeigte wird zum Hauptfenster (IsMainForm), und dessen Ende beendet üblicherweise das Programm.
Zwei Wege, ein Fenster zu zeigen:
| Aufruf | Verhalten |
|---|---|
app.ShowForm(f) | Fenster geht auf, der Aufruf kehrt sofort zurück; alle Fenster bleiben bedienbar |
app.ShowModal(f) | Der Aufruf kehrt erst zurück, wenn f.ModalResult gesetzt ist; er liefert diesen Wert |
→ Vega-Guides · Dialoge · Ereignisse
Ein zweites Fenster ist eine gewöhnliche TForm, die im Handler entsteht — kein Sonderweg:
var w: TForm := new TForm(260, 140, "Fenster 2");
…
g_app.ShowForm(w);
Vom Control zurück zu seinem Fenster führt Owner (seit dem Komponenten-Split ein TComponent; OwnerControl() liefert dasselbe schon als TControl):
fn OnNebenSchliessen(sender: TControl): void {
var f: TForm := sender.Owner as TForm;
f.Close();
}
Damit kommt ein Handler mit beliebig vielen gleichartigen Fenstern aus — statt für jedes eine eigene Modulvariable zu führen.
Close() liefert false, wenn ein OnClose-Handler mit CancelClose := true abgebrochen hat. Das eigentliche Zerstören übernimmt TApplication.
Ein modaler Dialog ist eine TForm, die über ShowModal gezeigt wird. Beendet wird er, indem ein Handler ModalResult setzt:
fn OnDlgOk(sender: TControl): void { g_dlg.ModalResult := mrOk; }
…
var r: int64 := g_app.ShowModal(g_dlg);
if (r == mrOk) { … }
ModalResult mrNone (0) ist, läuft die modale Schleife.mrCancel daraus.Position := POS_MAIN_CENTER setzt den Dialog mittig über das Hauptfenster.Hauptfenster, beliebig viele Nebenfenster, ein eigener modaler Dialog mit Rückgabewert:
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_haupt: TForm;
var g_stand: TLabel;
var g_zahl: int64;
// --- Ein weiteres, nicht-modales Fenster ------------------------------------
fn OnNebenSchliessen(sender: TControl): void {
// Owner ist der Weg vom Control zurueck zu seinem Fenster
var f: TForm := sender.Owner as TForm;
f.Close();
}
fn OnNeuesFenster(sender: TControl): void {
g_zahl := g_zahl + 1;
var w: TForm := new TForm(260, 140, StrConcat("Fenster ", IntToStr(g_zahl)));
var l: TLabel := new TLabel("Ein zweites Fenster.");
l.SetBounds(16, 16, 220, 18);
l.SetParent(w);
var b: TButton := new TButton("Schliessen");
b.SetBounds(16, 60, 120, 28);
b.OnClick := OnNebenSchliessen;
b.SetParent(w);
// ShowForm, nicht ShowModal: das Hauptfenster bleibt bedienbar
g_app.ShowForm(w);
}
// --- Ein eigener modaler Dialog ---------------------------------------------
var g_dlgFeld: TEdit;
var g_dlg: TForm;
fn OnDlgOk(sender: TControl): void { g_dlg.ModalResult := mrOk; }
fn OnDlgAbbruch(sender: TControl): void { g_dlg.ModalResult := mrCancel; }
fn OnFrage(sender: TControl): void {
g_dlg := new TForm(300, 150, "Name eingeben");
g_dlg.Position := POS_MAIN_CENTER;
var l: TLabel := new TLabel("Wie soll es heissen?");
l.SetBounds(16, 16, 260, 18);
l.SetParent(g_dlg);
g_dlgFeld := new TEdit("ohne Titel");
g_dlgFeld.SetBounds(16, 44, 260, 26);
g_dlgFeld.SetParent(g_dlg);
var ok: TButton := new TButton("OK");
ok.SetBounds(96, 90, 84, 28);
ok.OnClick := OnDlgOk;
ok.SetParent(g_dlg);
var ab: TButton := new TButton("Abbruch");
ab.SetBounds(192, 90, 84, 28);
ab.OnClick := OnDlgAbbruch;
ab.SetParent(g_dlg);
// ShowModal kehrt erst zurueck, wenn ModalResult gesetzt ist
var r: int64 := g_app.ShowModal(g_dlg);
if (r == mrOk) {
var t: pchar := g_dlgFeld.GetText();
g_stand.SetCaption(t);
} else {
g_stand.SetCaption("abgebrochen");
}
}
// --- Hauptfenster -----------------------------------------------------------
fn OnHauptSchliessen(sender: TControl): void {
g_app.Terminate();
}
fn main(): int64 {
g_app := new TApplication(NewPlatformBackend());
if (!g_app.Ready) { PrintLn("Kein Fenstersystem erreichbar."); return 1; }
g_zahl := 0;
g_haupt := new TForm(360, 200, "Hauptfenster");
g_stand := new TLabel("bereit");
g_stand.SetBounds(16, 16, 320, 18);
g_stand.SetParent(g_haupt);
var b1: TButton := new TButton("Neues Fenster");
b1.SetBounds(16, 56, 150, 28);
b1.OnClick := OnNeuesFenster;
b1.SetParent(g_haupt);
var b2: TButton := new TButton("Modaler Dialog");
b2.SetBounds(180, 56, 150, 28);
b2.OnClick := OnFrage;
b2.SetParent(g_haupt);
var b3: TButton := new TButton("Beenden");
b3.SetBounds(180, 104, 150, 28);
b3.OnClick := OnHauptSchliessen;
b3.SetParent(g_haupt);
// Das ERSTE gezeigte Fenster wird zum Hauptfenster
if (!g_app.ShowForm(g_haupt)) { return 2; }
g_app.Run();
g_app.Shutdown();
return 0;
}
Übersetzen: lyxc fenster.lyx -I . -I platform/linux -o fenster. Nachgemessen mit lyxc 1.1.3I, übersetzt fehlerfrei.
| Fall | Weg |
|---|---|
| Rückfrage, deren Antwort der Ablauf sofort braucht | ShowModal |
| Eigenschaften eines Objekts bearbeiten, Ergebnis übernehmen oder verwerfen | ShowModal |
| Zweites Dokument, Werkzeugpalette, Protokollfenster | ShowForm |
| Fortschrittsanzeige, die den Ablauf nicht anhalten soll | ShowForm |
Modale Fenster halten den aufrufenden Zweig an — was in einem Handler passiert, blockiert bis zur Antwort. Für lange Arbeiten ist das der falsche Weg; dort gehört ein nicht-modales Fenster plus Zeitgeber hin.
ModalResult nie gesetzt. Der Dialog lässt sich nur noch über den Fensterrahmen schließen; die modale Schleife läuft bis dahin weiter.TForm muss so lange leben, wie sie sichtbar ist; im Handler angelegte Fenster gehören der Anwendung, nicht dem Handler-Rahmen.Terminate() statt Close(). Terminate beendet die ganze Anwendung, Close nur das eine Fenster.
Letzte Aktualisierung: 2026-08-19 — Verhalten von ShowForm/ShowModal/Close gegen Vega/Forms.lyx erhoben; Beispiel mit lyxc 1.1.3I übersetzt.