Inhaltsverzeichnis

Vega — Mehrere Fenster und modale Abläufe

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


Weitere Fenster zur Laufzeit

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.


Eigene modale Dialoge

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) { … }


Beispiel

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.


Wann modal, wann nicht

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.


Fallstricke

Letzte Aktualisierung: 2026-08-19 — Verhalten von ShowForm/ShowModal/Close gegen Vega/Forms.lyx erhoben; Beispiel mit lyxc 1.1.3I übersetzt.