Form dynamisch bauen

Rund um die LCL und andere Komponenten
Antworten
Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Form dynamisch bauen

Beitrag von Mathias »

Bei diesem Mini-Code, wird ein Form dynamisch erzeugt.
Wen ich nun den Button1 klicke, erscheint das dynamische Form, aber leider wird mir der Constructor von TMyForm nicht aufgerufen. Die Caption wird geändert, nur wird das Form nicht rot, auch wird SchowModel nicht aufgerufen.

Was habe ich übersehen ?

Code: Alles auswählen

unit Unit1; 
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
 
type
  TMyForm = class(TForm)
    constructor Create(TheOwner: TComponent); override;
  end;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
constructor TMyForm.Create(TheOwner: TComponent);
begin
  inherited Create(TheOwner);
  Color := $FF;
  ShowMessage('abc');
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  f: TMyForm;
begin
  f := TMyForm.CreateNew(nil);
  f.Caption := 'Hello World';
  f.ShowModal;
  f.Free;
end;
 
end.


Wen ich anstelle von CreateNew, einfach Create aufrufe, kommt nur eine Fehlermeldung.

Code: Alles auswählen

Projekt project1 hat Exception-Klasse »EResNotFound« ausgelöst mit der Meldung:
Form resource TMyForm not found. For resourceless forms CreateNew constructor must be used. See the global variable RequireDerivedFormResource.
 
 In Datei 'include/customform.inc' in Zeile 2053

nil durch Self ersetzten bringt auch nichts.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Form dynamisch bauen

Beitrag von wp_xyz »

Lies halt die (ausnahmsweise sehr klare) Fehlermeldung: "For resourceless forms CreateNew constructor must be used"...

Mit CreateNew erzeugst du ein Formular, das keine lfm-Datei hat, sondern nur Laufzeit-Code verwendet. --> D.h. du solltest nicht den Constructor Create, sondern CreateNew implementieren; damit erscheint bei mir auch die Messagebox und das Formular wird rot.

Mit Create erzeugst du ein Formular zu dem es eine lfm Datei gibt. --> D.h. Wenn du in TForm1.Button1Click das Formular mit Create erzeugst, wird die lfm-Datei gesucht, und nicht gefunden.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Form dynamisch bauen

Beitrag von Mathias »

Mit CreateNew, so wie du schreibst, wird das Form rot.

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
 
type
  TMyForm = class(TForm)
    constructor CreateNew(TheOwner: TComponent);
  end;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R unit1.lfm}
 
constructor TMyForm.CreateNew(TheOwner: TComponent);
begin
  inherited CreateNew(TheOwner);
  Color := $FF;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  f: TMyForm;
begin
  f := TMyForm.CreateNew(nil);
  f.Caption := 'Hello World';
  f.ShowModal;
  f.Free;
end;
 
end.

Das override muss weg, ansonsten wird es nicht kompiliert. Dafür bekomme ich folgende Warnung.

Code: Alles auswählen

unit1.pas(12,17) Warning: An inherited method is hidden by "constructor CreateNew(TComponent);"


Wen ich es im "initialization" Teil mache, geht es mit einem einfachen Create. Wieso ?
Dies hatte ich von einem älteren Programm, das schon länger funktioniert. Nur will ich es jetzt im ButtonKlick,

Code: Alles auswählen

var
  f: TMyForm;
 
constructor TMyForm.Create(TheOwner: TComponent);
begin
  inherited Create(TheOwner);
  Color := $FF;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  f.Caption := 'Hello World';
  f.ShowModal;
end;
 
initialization
  f := TMyForm.Create(nil);
 
finalization
  FreeAndNil(f);
 
end.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Form dynamisch bauen

Beitrag von Mathias »

Müsste es im Wiki nicht auch CreateNew sein ?

Code: Alles auswählen

  MyForm:=TForm.CreateNew(nil);             // Formular erzeugen

anstelle

Code: Alles auswählen

  MyForm:=TForm.Create(nil);             // Formular erzeugen


http://wiki.freepascal.org/Form_Tutorial/de#Neues_Formular_dynamisch_erstellen
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten