Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - vorhandene Formulare dynamisch erzeugen / laden


Jakane - Sa 15.09.12 16:41
Titel: vorhandene Formulare dynamisch erzeugen / laden
Hallo Delhi-Helfer :)

Heute wollte ich ein Programm schreiben das mit vielen kleinen Formularen arbeitet.
Diese ganzen kleinen Formulare habe ich auch erstellt, aber damit das laden und pflegen leichter ist, wollte ich das über Objektlisten machen.

Quelltext
1:
2:
3:
4:
5:
  OLFormular.Add(mmKalender);
  OLFormular.Add(mmEssensfertigung);
  OLFormular.Add(mmEssensplan);
  OLFormular.Add(mmHausaufgaben);
  OLFormular.Add(mmTermine);

Das funktioniert schonmal.
Wenn ich nun einen entsprechenden Schalter klicke, bekomme ich den Index von dem Formular das ich laden möchte.
Und nun, will ich das Formular, so wie ich das erstellt habe, createn und laden:

Quelltext
1:
2:
3:
    Objekt:= (OLFormular.Items[Index]) as TForm;
    Objekt:= TForm.Create(Self);
    Objekt.Show;

Jetzt habe ich 1 Problem mit meinem Vorgehen.
Das Formular ist grau... Warscheinlich ein ganz neues und nicht das von mir erstellte.

Kann mir jemand erklären, wie ich mein Formular laden kann?

Danke für evtl. Hilfe :)


HelgeLange - Sa 15.09.12 16:47

weil Du immer die Basisklasse TForm erstellst. In der Objektliste müsstest Du die Objektklasse, nicht die Variable, ablegen.

Also wenn Du eine Form erstellst, Delphi erzeugt Dir eine Variablen-Definition wie MyForm : TMyForm.
Die Form erzeugst Du dann mit

Delphi-Quelltext
1:
MyForm := TMyForm.Create(Application);                    


Das heisst, Du legst in Deiner Liste in dem Fall die classenreferenz TMyForm ab und nicht MyForm, was nur eine leere Variable ist.


Jakane - Sa 15.09.12 16:52

user profile iconHelgeLange hat folgendes geschrieben Zum zitierten Posting springen:
weil Du immer die Basisklasse TForm erstellst. In der Objektliste müsstest Du die Objektklasse, nicht die Variable, ablegen.

Also wenn Du eine Form erstellst, Delphi erzeugt Dir eine Variablen-Definition wie MyForm : TMyForm.
Die Form erzeugst Du dann mit

Delphi-Quelltext
1:
MyForm := TMyForm.Create(Application);                    


Das heisst, Du legst in Deiner Liste in dem Fall die classenreferenz TMyForm ab und nicht MyForm, was nur eine leere Variable ist.



Quelltext
1:
2:
3:
4:
5:
  OLFormular.Add(TmmKalender);
  OLFormular.Add(TmmEssensfertigung);
  OLFormular.Add(TmmEssensplan);
  OLFormular.Add(TmmHausaufgaben);
  OLFormular.Add(TmmTermine);


[Fehler] Haupt.pas(165): Inkompatible Typen: 'TObject' und 'Class reference'

Ich kann keine TForm in meine Objektliste packen :(


HelgeLange - Sa 15.09.12 17:49

Du kannst aber records in eine TList packen zum Bsp. UNd ein record wiederrum kann auch die Formvariable und die Klassenreferenz enthalten


haentschman - Sa 15.09.12 18:01

Hallo...

ich finde ihr redet an einander vorbei.

Ich fasse mal zusammen wie es funktioniert:

1. Form ganz normal designen. (Name z.B. MyForm1,MyForm2 etc.)
2. Form erzeugen
3. Erzeugtes Objekt in Objectlist
sinngemäß:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var aForm: TForm;
.
.
aForm:= TMyForm1.Create(Application);
ObjectList.Add(aForm);
aForm:= TMyForm2.Create(Application);
ObjectList.Add(aForm);


4. über den Index dann zugreifen. Cast auf TForm nicht vergessen.

Delphi-Quelltext
1:
TForm(ObjectList[0]).Width:= 100;                    


...sollte wie mit jedem anderen Object auch mit TForm gehen. Aber ungetestet.


Jakane - Sa 15.09.12 19:26

user profile iconhaentschman hat folgendes geschrieben Zum zitierten Posting springen:
Hallo...

ich finde ihr redet an einander vorbei.

Ich fasse mal zusammen wie es funktioniert:

1. Form ganz normal designen. (Name z.B. MyForm1,MyForm2 etc.)
2. Form erzeugen
3. Erzeugtes Objekt in Objectlist
sinngemäß:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var aForm: TForm;
.
.
aForm:= TMyForm1.Create(Application);
ObjectList.Add(aForm);
aForm:= TMyForm2.Create(Application);
ObjectList.Add(aForm);


4. über den Index dann zugreifen. Cast auf TForm nicht vergessen.

Delphi-Quelltext
1:
TForm(ObjectList[0]).Width:= 100;                    


...sollte wie mit jedem anderen Object auch mit TForm gehen. Aber ungetestet.


Ja ungetestet... ich merks :(
Formular ist weiterhin grau und nicht das Formular das ich erstellt habe.


haentschman - Sa 15.09.12 19:56

Ja dann liegt der Hase wo anders im Pfeffer... 8)
Habe es eben getestet... funktioniert.

Hauptform mit einem Button:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Contnrs;

type
  TForm1 = class(TForm)
    btn1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btn1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    FObjectList: TObjectList;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);
var aForm: TForm;
begin
  FObjectList.Clear;
  aForm:= TForm2.Create(nil);
  FObjectList.Add(aForm);
  TForm(FObjectList[0]).ShowModal;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FObjectList:= TObjectList.Create;
  FObjectList.OwnsObjects:= True;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FObjectList.Free;
end;

end.


Nebenform mit einer Checkbox, Hintergrund gelb:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm2 = class(TForm)
    chk1: TCheckBox;
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}


end.


...und es funktioniert. Die 2. Form wird brav mit Checkbox und gelbem Hintergrund angezeigt.


Jakane - So 16.09.12 13:02

ich denke das kann wirklich funktionieren, wenn meine formulare keine mdi wären ^^ danke


haentschman - So 16.09.12 13:10

Moin...
Zitat:
wenn meine formulare keine mdi wären

und woher sollen wir das wissen wenn du wichtige Info´s für dich behälst ?


bummi - So 16.09.12 13:28

Ein IMHO netter Ansatz wäre, eine Liste mit den Klassennamen und dann


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
Function CreateWindow(Classname:String;Owner:TComponent):TComponent;
var
 CC:TComponentClass;
begin
  CC :=  TComponentClass(GetClass(Classname));
  Result := TForm(CC.Create(Owner));
end;

//BSP:
procedure TForm2.Button1Click(Sender: TObject);
begin
  TForm(CreateWindow('TForm2',self)).Show;
end;


//wobei alle Forms eine Initializationsabschnitt beinhalten in der Art

initialization
RegisterClass(TForm1);