1. Zwei Formulare
Wir erstellen eine Popup-Funktion mit Form1 (Hauptformular) und Form2 (Popup-Fenster)
1. Schritt-für-Schritt Anleitung
- Neues Projekt erstellen, ziehe einen Button1 auf Form1, setze
Caption = Open Form2und erzeuge dasOnClick-Ereignis (du kannst einfach doppelt auf den Button im Formulardesign klicken, um das Klickereignis schnell anzulegen); - Über das obere Menü
File → New Formein zweites Formular Form2 erstellen; - Auf Form2 einen Button1 platzieren,
Caption = Closevergeben und das zugehörigeOnClick-Ereignis erstellen; - Tastenkürzel zum Wechseln zwischen Formularen:
Shift+F12Formularliste aufrufen /F12zwischen Design- und Codeansicht umschalten; - Unit2 in Unit1 einbinden: Füge
Unit2im Bereichinterface useshinzu.
Unit1 (Hauptformular)
Zwei wichtige Stellen sind zu beachten: Unit2; // Einbindung von Unit2
Zweitens rufen wir im Klick-Handler das zweite Fenster als modales Dialogfenster auf: Form2.ShowModal; // Modales Öffnen von Form2
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Unit2; // Unit2 einbinden
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.ShowModal; // Modales Öffnen von Form2
end;
end.
Unit2 (Unterformular)
So fügst du das zweite Formular zum Projekt hinzu

Nach dem Hinzufügen erscheint ein neuer Reiter im Editor
Einer für den Quellcode des Hauptfensters, einer für den Code von Form2


Um Form2 zu bearbeiten, wähle Unit2 aus und drücke F12, dann öffnet sich die Designansicht von Form2

Füge wie in den vorherigen Lektionen einen Button hinzu, setze seine Beschriftung auf Close und implementiere die Schließfunktion. Das hast du bereits gelernt, du kannst es selbst ausprobieren.
unit Unit2;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TForm2 }
TForm2 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form2: TForm2;
implementation
{$R *.lfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
Close; // Schließe das aktuelle Form2
end;
end.

2. Kernunterschied zwischen Show und ShowModal (Vergleichsbeispiel)
Oberfläche anpassen
Füge zwei Buttons auf Form1 hinzu:
- btnShow: Caption = Show
- btnShowModal: Caption = ShowModal

// Nicht-modales Fenster mit Show
procedure TForm1.btnShowClick(Sender: TObject);
begin
Form2.Show;
ShowMessage('Form2 wurde geöffnet, das Hauptformular bleibt bedienbar');
end;
// Modales Fenster mit ShowModal
procedure TForm1.btnShowModalClick(Sender: TObject);
begin
Form2.ShowModal;
ShowMessage('Dieser Hinweis erscheint erst, wenn Form2 geschlossen wurde');
end;Code-Sprache: JavaScript (javascript)
Erläuterung der Unterschiede
Show(nicht-modal)
- Der Code läuft sofort weiter, nachdem das Unterfenster geöffnet wurde;
- Das Hauptformular bleibt verschiebbar und alle anderen Buttons sind anklickbar;
- Entspricht
Form2.Visible := True;, das Fenster wird automatisch nach vorne geholt.
ShowModal(modales Dialogfenster)
- Die Codeausführung pausiert, bis das Unterfenster geschlossen wird;
- Das Hauptformular ist gesperrt und kann nicht bedient werden;
- Es handelt sich um eine Funktion, mit deren Rückgabewert
ModalResultdu prüfen kannst, wie das Fenster geschlossen wurde.
Kurz zusammengefasst: Bei einem modalen Fenster musst du zuerst das Unterfenster schließen, bevor du wieder mit dem Hauptfenster arbeiten kannst. Bei einem nicht-modalen Fenster kannst du beide Fenster gleichzeitig bedienen.
3. Gegenseitiger Aufruf von Formularen: Fehler bei zyklischen Einbindungen beheben
Anforderung: Form1 öffnet Form2, Form2 öffnet Form1
Wenn du beide Units gegenseitig im Bereich interface uses einbindest, entsteht ein Fehler durch zyklische Abhängigkeit. Lösung: Platziere die Einbindung im Abschnitt implementation
Unit1
unit Unit1;
interface
uses Forms,StdCtrls;
type
TForm1=class(TForm)
Button1:TButton;
procedure Button1Click(Sender:TObject);
end;
var Form1:TForm1;
implementation
uses Unit2; // Einbindung hier platzieren
{$R *.lfm}
procedure TForm1.Button1Click(Sender:TObject);
begin
Form2.Show;
end;
end.
Unit2
unit Unit2;
interface
uses Forms,StdCtrls;
type
TForm2=class(TForm)
Button1:TButton;
procedure Button1Click(Sender:TObject);
end;
var Form2:TForm2;
implementation
uses Unit1; // Gegenseitige Einbindung im Implementationsbereich
{$R *.lfm}
procedure TForm2.Button1Click(Sender:TObject);
begin
Form1.Show;
end;
end.
4. Werte zwischen Formularen übergeben (Beispiel mit öffentlichen Member-Variablen)
Funktion: Beim Öffnen des Unterfensters vom Hauptformular wird ein Zähler hochgezählt, das Unterfenster kann die Anzahl der Öffnungen anzeigen
Öffentliche Ganzzahlvariable in Unit2 definieren
type
TForm2 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
public
Count: Integer; // Öffentliche Variable, auf die Unit1 zugreifen kann
end;
Zähler inkrementieren beim Klick auf den Button in Unit1
procedure TForm1.Button1Click(Sender: TObject);
begin
Inc(Form2.Count); // Zähler um 1 erhöhen
Form2.ShowModal;
end;Code-Sprache: JavaScript (javascript)
Anzeige der Öffnungsanzahl in Unit2
procedure TForm2.Button1Click(Sender: TObject);
begin
ShowMessage('Dieses Formular wurde '+IntToStr(Count)+' Mal geöffnet');
end;Code-Sprache: JavaScript (javascript)
Empfehlung zur sauberen Programmierung: Vermeide nach Möglichkeit globale oder öffentliche Variablen, nutze stattdessen Properties zur Wertübergabe.
5. Dynamische Erstellung von Formularen
Ohne automatisch generierte globale Form-Variable des Projekts arbeiten
Methode 1: Dynamische Instanz des entworfenen Form2
- Öffne die Datei
Project.lprund entferne die ZeileApplication.CreateForm(TForm2, Form2); - Code für den Button auf Form1:
procedure TForm1.Button1Click(Sender: TObject);
var
frm2: TForm2;
begin
frm2 := TForm2.Create(nil); // Manuelle Erstellung der Instanz
frm2.ShowModal;
FreeAndNil(frm2); // Speicher freigeben, um Speicherlecks zu vermeiden
end;Code-Sprache: JavaScript (javascript)
Methode 2: Vollständige Generierung eines Formulars per Code (ohne vorheriges Design)
Beim Klick auf den Button wird ein komplett neues Fenster mit integriertem Schließbutton erstellt
unit Unit1;
interface
uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
procedure DynamicBtnClick(Sender: TObject); // Eigenes Klickereignis für dynamischen Button
public
end;
var Form1: TForm1;
implementation
{$R *.lfm}
procedure TForm1.DynamicBtnClick(Sender: TObject);
begin
ShowMessage('Das dynamische Fenster wird bald geschlossen');
TForm(TButton(Sender).Parent).Close;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
MyForm: TForm;
MyBtn: TButton;
begin
MyForm := TForm.Create(nil);
MyForm.SetBounds(100,100,220,150);
MyForm.Caption := 'Dynamisch erstelltes Formular';
// Button erstellen, Eigentümer ist MyForm – der Button wird automatisch beim Schließen des Fensters zerstört
MyBtn := TButton.Create(MyForm);
MyBtn.SetBounds(10,10,200,30);
MyBtn.Caption := 'Fenster schließen';
MyBtn.Parent := MyForm;
MyBtn.OnClick := @DynamicBtnClick;
MyForm.ShowModal;
FreeAndNil(MyForm);
end;
end.
Meldung „Choose Debug Information format“ erscheint



Einfach das passende Debug-Format auswählen, dann läuft alles normal.
Mehrere Formulare in Lazarus