Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Formular beliebig oft zur Laufzeit erstellen (https://www.delphipraxis.net/54999-formular-beliebig-oft-zur-laufzeit-erstellen.html)

Sko 14. Okt 2005 20:29


Formular beliebig oft zur Laufzeit erstellen
 
Ich habe ein Programm erstellt, in dem ich ein Formular beliebig oft erstellen möchte. Es soll mal ein Chatprogramm werden und ich möchte für jeden Chatpartner ein eigenes Fenster erstellen, so wie bei ICQ. Ich hab das so versucht:

Delphi-Quellcode:
procedure TForm1.BNachrichtClick(Sender: TObject);
begin
  Form2.Create(Form1);
  Form2.Name.Caption:=Kliste.Selected.Caption;
  Form2.Nr.Caption:=Kliste.Selected.SubItems[0];
  Form2.Show;
end;
aber da bekomme ich jedes mal eine Fehlermeldung. Ich hab das Formular auch aus den Auto-Create-Forms genommen.

Wie macht man das richtig?

dahead 14. Okt 2005 20:34

Re: Formular beliebig oft zur Laufzeit erstellen
 
Du musst (kannst) deine ganzen Formulare in einem Array oder einer Liste dynamisch speichern.
dann kannst du auch das mit dem .Name usw. weglassen.

Wenn du nur ein formular statisch verwendest und das nochmal Create'n willst, kommt der fehler.

Union 14. Okt 2005 20:44

Re: Formular beliebig oft zur Laufzeit erstellen
 
Du kannst das auch so machen (wenn Du keine weitere Verwaltung brauchst):
Delphi-Quellcode:
procedure TForm1.BNachrichtClick(Sender: TObject);
begin
  With TForm2.Create(Self) do
  begin
    Name.Caption := Kliste.Selected.Caption;
    Nr.Caption  := Kliste.Selected.SubItems[0];
    Show;
  end;
end;

Sko 14. Okt 2005 21:18

Re: Formular beliebig oft zur Laufzeit erstellen
 
danke! es funktioniert :thumb:

Jarmen_Kell 14. Okt 2005 21:19

Re: Formular beliebig oft zur Laufzeit erstellen
 
Du könntest dir auchn Knopf an die Backe nähen...

Da gesagt wurde, dass es für ein Chatprogramm ist, kann man wohl davon ausgehen, dass das ganze später noch verwendet werden muss :wink:

Projektsource:

Delphi-Quellcode:
program Formulare;

uses
  Forms,
  Main in 'Main.pas' {MainForm},
  chat in 'chat.pas' {ChatForm};

{$R *.RES}

begin
  Application.Initialize;
  Application.CreateForm(TMainForm, MainForm); // ChatForm nicht erstellen!
  Application.Run;
end.
So nun vom MainForm
Delphi-Quellcode:
uses Chat
type PChatForm = ^ChatForm; // ein Pointer auf das Formular

type
  TMainForm = class(TForm)
...

  public
    FormListe: TList; // Eine Liste, in der die Pointer auf die Formulare gespeichert werden
    ChatPointer: PChatFormForm; // Eine Pointervariable (Definition oben)
Wenn du jetzt ein Formular erzeugen willst, musst du folgendes machen:
Delphi-Quellcode:
procedure TMainForm.CreateButtonClick(Sender: TObject);
begin
  GetMem(ChatPointer, SizeOf(TChatForm)); // An Adresse Speicher fürs Formular bereitstellen
  ChatPointer^ := TChatForm.Create(Self); // ChatForm erzeugen
  FormListe.Add(ChatPointer); // fügt den Pointer zur Liste hinzu
end;
Der Zugriff auf eines der Formulare geschieh wie folgt:
Delphi-Quellcode:
  ChatPointer := FormListe[Integer]; // Pointer auf ein Formular richten
  ChatPointer^.Caption := EditFormCaption.Text;
Da du den ganzen Speicher selber reserviert hast, musst du ihn auch wieder freigeben.
Delphi-Quellcode:
var
  i: Integer;
begin
  for i := 0 to FormListe.Count-1 do
  begin
    ChatPointer := FormListe[i];
    ChatPointer^.Hide; // Sicherheitshalber aufrufen, da es sonst zu Fehlern kommen kann
    ChatPointer^.Free;
    FreeMem(ChatPointer, SizeOf(TChatFormForm)); // Speicher wieder freigeben
  end;
  FormListe.Free;
Das waren so die trockenen Befehle.

Nun denn, da du darauf nicht selber gekommen bist, nehme ich an, dass du dich noch nicht mit dem Thema "Pointer" beschäftigt hast. Dazu würde ich dir nun raten (Ausnahme: Du willst ein CnP-Prog), dich damit intensiv zu beschäftigen. Ist anfangs schwierig zu verstehen (wozu auch selbstständiges Beherrschen gehört), aber für dein Programm unabdingbar. Hier im Forum wirst du einiges dazu finden.

lizardking 14. Okt 2005 23:15

Re: Formular beliebig oft zur Laufzeit erstellen
 
Irgendwie steig ich hier ja jetzt mal gar nicht durch. Bin auch ehrlich gesagt noch recht neu, was Delphi angeht ( < 6 Monate). Aber hier wird dem Threadstarter was von Arrays und Pointern und was weiss ich nicht erzaehlt und daher meine Frage, ob ich falsch liege :

Delphi-Quellcode:
Form2.Create(Form1);
Das ist meiner Meinung nach der allererste Punkt, wo es schon hakt. Muesste doch lauten :

Delphi-Quellcode:
Form2 := TForm2.Create(Form1);
So jedenfalls das, was ich erstmal beim Umstieg auf Delphi schmerzlich lernen musste (was mir allerdings mittlerweile mehr als logisch erscheint). Die Hinweise auf moegliche Verwaltung per Arrays oder Pointer in allen Ehren, da steckt ja auch hintergruendig in den gegebenen Quellcodes die richtige Anwendung drin. Aber beim naechsten Mal steht man (in diesem Falle der Threadstarter) wieder da, da die eigentlichen Grundlagen noch nicht verstanden sind.

Mich fasziniert momentan noch gerade dieses konsequente Denken bei Delphi wie "man kann keine Create-Methode auf einem Objekt ausfuehren, dass es noch gar nicht gibt". Entweder ich hab da was falsch verstanden oder ich frage mich, warum hier nicht so etwas weitergegeben wird bevor mit "komplizierten" Datenstrukturen losgelegt wird.

Gruesse,

Lizzy

dahead 15. Okt 2005 00:25

Re: Formular beliebig oft zur Laufzeit erstellen
 
@lizardking:

mhh, also so ganz versteh ich dein 'problem' jetzt nicht.

Zitat:

Aber beim naechsten Mal steht man (in diesem Falle der Threadstarter) wieder da, da die eigentlichen Grundlagen noch nicht verstanden sind.
wenn man, wie der threadstarter ein icq-ähnliches programm machen möchte, und dies pro kontakt in der liste verschiedene nachrichten-fenster (mit verschiedenem inhalt usw.) besitzt, erstellen will, so kann man dies nur über listen/arrays u.ä. lösen. wenn man sowas also programmieren will, muss man logischerweise auch diese grundlagen lernen.

so weist du den variablen des typs TForm f1 und f2 eine neue Instanz einer TForm zu:
Delphi-Quellcode:
var
 f1, f2: TForm;
begin
 f1 := TForm.Create(MainForm);
 f2 := TForm.Create(MainForm);
end;
wenn du schreibst:

Delphi-Quellcode:
Form2 := TForm2.Create(Form1);
dann weist du der variablen form2 eine Instanz des Typs TForm2 zu (in diesem fall wohl das nachrichten fenster). du kannst es also unter der variablen Form2 nur einmal erstellen. und um dies mehrfach zu erledigen braucht er bspw. einen Array of TForm2 usw.

hoffe das ging jetzt nicht am thema vorbei.

lizardking 15. Okt 2005 01:16

Re: Formular beliebig oft zur Laufzeit erstellen
 
Zitat:

Zitat von dahead
@lizardking:
mhh, also so ganz versteh ich dein 'problem' jetzt nicht.

Merk ich schon.

Zitat:

Zitat von dahead
@lizardking:
Zitat:

Zitat von lizardking
Aber beim naechsten Mal steht man (in diesem Falle der Threadstarter) wieder da, da die eigentlichen Grundlagen noch nicht verstanden sind.

wenn man, wie der threadstarter ein icq-ähnliches programm machen möchte, und dies pro kontakt in der liste verschiedene nachrichten-fenster (mit verschiedenem inhalt usw.) besitzt, erstellen will, so kann man dies nur über listen/arrays u.ä. lösen. wenn man sowas also programmieren will, muss man logischerweise auch diese grundlagen lernen.

Ist doch gut und schoen, wenn man erfaehrt, dass man solche Form-Objecte in einem Array oder wie auch immer speichern kann. Aber schau Dir mal Deine Beispiele an und das des Threadstarters.

[delphi]
x := Tx.Create;
[delphi]

und NICHT

[pre]
x.Create;
[/pre]

Also Constructor-Aufruf als (wie ich es bei anderen Programmiersprachen interpretieren wuerde) statische Methode einer Klasse. Funktioniert sicherlich auch, wenn x bereits eine bereits initialisierte Objektvariable ist, waere aber nach meinen bisherigen Erfahrungen unsauber.
Und ich gehe davon aus, dass genau das der Grund fuer die Fehlermeldungen ist. Und deshalb finde ich es sinnvoller genau zu sagen, warum das Vorgehen nicht funktioniert, anstatt Code-Schnippsel zu liefern.

Lasse mich gerne belehren, aber meiner Meinung nach liegt der Fehler primaer an genau diesem Punkt.

Gruss, Lizzy

dahead 15. Okt 2005 01:31

Re: Formular beliebig oft zur Laufzeit erstellen
 
also ich hab ihm keine codeschnipsel geliefert, eher eine grundsätzliche richtung (arrays/listen o.ä.), da ich annahm, dass er den folgenden aufruf

Zitat:

Zitat von sko
Delphi-Quellcode:
procedure TForm1.BNachrichtClick(Sender: TObject);
begin
  Form2.Create(Form1);
  Form2.Name.Caption:=Kliste.Selected.Caption;
  Form2.Nr.Caption:=Kliste.Selected.SubItems[0];
  Form2.Show;
end;

mehrfach durchführt, und zwar für jede nachricht einmal. und wenn man halt zwei mal Form2.Create ausführt kommt es zu einem fehler, da es bereits existiert. nur das wollte ich mit obigem andeuten.

Zitat:

Lasse mich gerne belehren, aber meiner Meinung nach liegt der Fehler primaer an genau diesem Punkt.
davon gehe ich auch aus.

aber so wie es aussieht meldet sich der threadstarter nicht mehr, bzw. ist bereits glücklich.

Union 15. Okt 2005 09:14

Re: Formular beliebig oft zur Laufzeit erstellen
 
Zitat:

Zitat von dahead
also ich hab ihm keine codeschnipsel geliefert, eher eine grundsätzliche richtung (arrays/listen o.ä.), da ich annahm, dass er den folgenden aufruf

Zitat:

Zitat von sko
Delphi-Quellcode:
procedure TForm1.BNachrichtClick(Sender: TObject);
begin
  Form2.Create(Form1);
  Form2.Name.Caption:=Kliste.Selected.Caption;
  Form2.Nr.Caption:=Kliste.Selected.SubItems[0];
  Form2.Show;
end;

mehrfach durchführt, und zwar für jede nachricht einmal. und wenn man halt zwei mal Form2.Create ausführt kommt es zu einem fehler, da es bereits existiert. nur das wollte ich mit obigem andeuten.

Das Problem lag aber nicht an der Mehrfachausführung. Beim Start der Application existiert Form2 als globale Variable mit dem Wert nil. Es schlägt dadurch schon beim ersten Aufruf fehl. Denn der constructor muss natürlich mit TForm.Create aufgerufen werden, also dem constructor der Klasse.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:33 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz