![]() |
Konzeptfrage FormCreate
Hallo Gemeinde,
ich möchte aufgrund der mehrfachen Nutzung das Erzeugen meiner Formulare in eine Funktion auslagern. Meine Ansätze hierzu funktionieren soweit auch, jedoch verhält sich das ganze in manchen Fällen ein wenig mehrwürdig:
Delphi-Quellcode:
aber: nachdem die Form erzeugt wurde prüfe ich mit:
function createform(AOwner:TFormClass;nform:TForm):boolean;
Begin try application.CreateForm(aowner,nform); nform.Parent:=mainform.panel_df; mainform.Notebook1.Visible:=false; nform.Show; result:=true; except result:=false; end; end; //Aufruf: createform(TForm1,Form1); //Funktioniert
Delphi-Quellcode:
Hier wird seltsamerweise immer false zurückgegeben. Setze ich anstelle des Aufrufes der Funktion, die Funktion selbst mit den entsprechenden Werten ein, wird auf die Prüfung der zugehörige Code ausgeführt. Meine Vermutung ist nun, dass ich mit den Typen der Parameter etwas vermasselt habe. Leider ist die Delphi 7 Hilfe hier jedoch nicht sehr auskunftsfreudig....also hoffe ich, dass ihr mir helfen könnt.
if assigned(form1) then machwas
Vielen Dank! //EDIT: ist die Funktionsbezeichnung kritisch? |
Re: Konzeptfrage FormCreate
Probier mal
Delphi-Quellcode:
Ohne VAR wird innerhalb der function eine Kopie von "nform" benutzt (call by value), du möchtest aber das Ergebnis (die Adr. der TForm Instanz) ausserhalb der function verwenden (call by reference)
function createform(AOwner:TFormClass; VAR nform:TForm):boolean;
PMM |
Re: Konzeptfrage FormCreate
Hallo,
danke für die Rückmeldung. Mit der Version bekomme ich Probleme beim Aufruf:
Delphi-Quellcode:
createform(TForm1,Form1)
"[Fehler] Customize.pas(378): Die Typen der tatsächlichen und formalen Var-Parameter müssen übereinstimmen" |
Re: Konzeptfrage FormCreate
Wie hast du den Form1 deklariert?
|
Re: Konzeptfrage FormCreate
Naja, wie eine Form halt deklariert wird:
Delphi-Quellcode:
TForm1 = class(TForm)
private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; |
Re: Konzeptfrage FormCreate
Hallo,
Form1 ist ja auch vom Type TForm1 und nicht vom Type TForm, Du benötigst hier also noch einen entsprechenden Typecast. Ob das so in der von Dir gewünschten Form geht, weiß ich nicht. Eventuell könnte ja sowas in dieser Art funktionieren (nicht getestet)
Delphi-Quellcode:
function createform(AOwner: TFormClass ; var nform {typloser Parameter} ):boolean;
Begin result := false; try if nForm is TForm then begin application.CreateForm(AOwner,nform); nform.Parent := mainform.panel_df; mainform.Notebook1.Visible := false; nform.Show; result := true; end; except end; end; |
Re: Konzeptfrage FormCreate
Noch was:
Delphi-Quellcode:
Der erste Parameter ist die FormClass und nicht der Owner. Du solltest diesen dann auch nicht aOwner nennen.
application.CreateForm(AOwner,nform);
PMM |
Re: Konzeptfrage FormCreate
Ich habe das ganze mal aus meinem Projekt herausgelöst und neu aufgesetzt:
Delphi-Quellcode:
Casten ließ sich der Typ nicht.
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Panel1: TPanel; procedure Button1Click(Sender: TObject); function formerzeugen(fclass:TFormClass;var nform):boolean; private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation uses unit2; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin formerzeugen(TForm2,form2); end; function TForm1.formerzeugen(fclass:TFormClass;var nform):boolean; Begin application.CreateForm(fclass,nform); (nform as TForm).show //geht nicht :[Fehler] Unit1.pas(39): Operator ist auf diesen Operandentyp nicht anwendbar end; end. ////////////////////////////////////////////// unit Unit2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm2 = class(TForm) Label1: TLabel; private { Private-Deklarationen } public { Public-Deklarationen } end; var Form2: TForm2; implementation {$R *.dfm} end. |
Re: Konzeptfrage FormCreate
So sollte es gehen:
Zitat:
|
Re: Konzeptfrage FormCreate
Hallo,
funktioniert!! Nun fehlt mir jedoch noch das Verständnis dazu:
Delphi-Quellcode:
Kannst du evtl. mal 1-2 Sätze dazu verlieren?
formerzeugen(TForm2,TForm(form2));
//bzw function TForm1.formerzeugen(fclass:TFormClass;var nform:Tform):boolean; Vielen Dank |
Re: Konzeptfrage FormCreate
Zitat:
Für Application.CreateForm ist nur die Objektvariable wichtig, da der Klassentyp gesondert übergeben wird. Also casten wir das Ganze zu TForm und es funktioniert. |
Re: Konzeptfrage FormCreate
Der "as" operator setzt einen Nachfolger von TObject voraus. nform ist jetzt aber eine untypisierte Refrenz, über die der Compiler keine weiteren Annahmen machen darf.
Du hast zwei Optionen: TForm(nform).Show ... benutzen - damit übernimmst du die Verantwortung das der cast OK ist. Oder den nform parameter typisieren:
Delphi-Quellcode:
verwenden. Dann klappt das ohne cast. Ich würde dann aber auch den ersten Parameter komplett entfernen, denn es wird ja nun immer eine TForm1 Instanz erstellt. Also:
function formerzeugen(fclass:TFormClass;var nform : Tform1):boolean;
Delphi-Quellcode:
PMM
function formerzeugen(var nform : Tform1):boolean;
|
Re: Konzeptfrage FormCreate
Vielen Dank für die Ausführungen. Das schafft mal wieder ein wenig mehr Klarheit!!
|
Re: Konzeptfrage FormCreate
Wie wäre es denn, wenn du ganz banal eine Funktion anstelle der Prozedur nehmen würdest:
Delphi-Quellcode:
HTH,
function CreateForm(AOwner: TFormClass): TForm;
begin Application.CreateForm(AOwner, Result); try Result.Parent := mainform.panel_df; mainform.Notebook1.Visible := false; Result.Show; except Result := nil; end; end; Uli. |
Re: Konzeptfrage FormCreate
Zitat:
Aber wenn in Result.Show eine Exception auftritt, setzt du Result einfach auf NIL? Ich weiß ja nicht.... |
Re: Konzeptfrage FormCreate
Da das Ergebnis der Funktion vom typ TForm ist sollte diese doch mit
Delphi-Quellcode:
aufgerufen werden,was jedoch in einer Fehlermeldung:
form2:=createform(TForm2);
[Fehler] Unit1.pas(31): Inkompatible Typen: 'TForm2' und 'TForm' endet. Oder habe ich hier nen Denkfehler? |
Re: Konzeptfrage FormCreate
Zitat:
|
Re: Konzeptfrage FormCreate
Zitat:
Delphi-Quellcode:
Form2 := TForm2(createform(TForm2));
|
Re: Konzeptfrage FormCreate
Irgendwie wird keine Form erzeugt, wenngleich die Funktion ordnungsgemäß durchläuft....
|
Re: Konzeptfrage FormCreate
Wie rufst du sie auf?
Delphi-Quellcode:
funktioniert bei mir ohne Probleme.
var
f : TForm; begin Application.CreateForm(TForm, f); f.Parent := Panel1; f.Visible := TRUE; f.Show; end; |
Re: Konzeptfrage FormCreate
Klar... die Funktion von uligerhardt weiter oben funktioniert nicht. Ich habe es mit dem Cast von Zoot umgesetzt.
|
Re: Konzeptfrage FormCreate
Hallo WIng2005,
also normalerweise braucht man für die Übergabe eines Objektes kein var-Parameter, weil es sich schon um einen Zeiger handelt. Hast Du das neu Erstelltes Formular unter Projektoptionen von Automatisch erzeugtes auf Verfügbares Form gestellt? Des weiteren würde ich die Procedure:
Delphi-Quellcode:
unter public schreiben damit man kein Problem mit der Sichtbarkeit bekommt.
function formerzeugen(fclass:TFormClass;var nform):boolean;
Bis bald Chemiker |
Re: Konzeptfrage FormCreate
Zitat:
Delphi-Quellcode:
Form2 auf die neu erstellte Instanz verweisen.
formerzeugen(TForm2,TForm(form2));
|
Re: Konzeptfrage FormCreate
Hallo,
die Frage der Sichtbarkeit wie auch die Einstellungen in den Projektoptionen hatte ich berücksichtigt. Ich werde mir die Referenz/Wertparameterübergabe heute abend nocheinmal anschauen. Erstmal habe ich (zumindest für mein Projekt) eine funktionierende Lösung. Der Lerneffekt muss leider bis nach der Arbeit warten... :? |
Re: Konzeptfrage FormCreate
Hallo WIng2005,
ich bin mir immer noch unsicher, ob ich Deine Frage richtig verstanden habe. Ich arbeite bevorzugt mit einer Lösung wo das Fenster selber für die Erstellung und Zerstörung zuständig ist. Mal ein Beispiel: Zuerst die Class-Unit für die Daten ist nicht besonderes nur zum Spielen.
Delphi-Quellcode:
So nun das Hauptformular:
unit uPersonenKlasse;
interface uses Classes; type THPLPersonen= Class (TObject) private FVorName: String; FNachName: String; procedure GetFNachName(const Value: String); procedure GetFVorName(const Value: String); function SetFNachName: String; function SetFVorName: String; public property VorName: String read SetFVorName write GetFVorName; property NachName: String read SetFNachName write GetFNachName; End; implementation { THPLPersonen } procedure THPLPersonen.GetFNachName(const Value: String); begin if Value <> FNachName then begin FNachName:= Value end; end; procedure THPLPersonen.GetFVorName(const Value: String); begin if Value <> FVorName then begin FVorName:= Value end; end; function THPLPersonen.SetFNachName: String; begin result:= FNachName; end; function THPLPersonen.SetFVorName: String; begin result:= FVorName; end; end.
Delphi-Quellcode:
Ist eigentlich nichts Besonderes, bis auf die Zeile wo das Dynamische -Formular aufgerufen wird.
unit frmHauptFenster;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, uPersonenKlasse, uDynamischesFenster; type TfrmMainForm = class(TForm) edVorName: TEdit; edNachName: TEdit; btFormOeffnen: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure btFormOeffnenClick(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } FPersonen: THPLPersonen; end; var frmMainForm: TfrmMainForm; implementation {$R *.dfm} procedure TfrmMainForm.btFormOeffnenClick(Sender: TObject); begin FPersonen.VorName:= edVorName.Text; FPersonen.NachName:= edNachName.Text; TfrmAufgerufen.FormAufrufen(FPersonen); // Dynamische –Formular aufrufen edVorName.Text:= FPersonen.VorName; edNachName.Text:= FPersonen.NachName; end; procedure TfrmMainForm.FormCreate(Sender: TObject); begin FPersonen:= THPLPersonen.Create; end; procedure TfrmMainForm.FormDestroy(Sender: TObject); begin FPersonen.Free; end; end. Nun kommt, dass dynamische Form:
Delphi-Quellcode:
Zu beachten ist das die Eigenschaft ModalResult vom OK-Button auf mrOK gestellt wird.
unit uDynamischesFenster;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, uPersonenKlasse; type TfrmAufgerufen = class(TForm) edVorName: TEdit; edNachName: TEdit; btAbbruch: TButton; btOK: TButton; procedure btOKClick(Sender: TObject); private FPersonenKopie: THPLPersonen; procedure EditFelderFuellen; public class procedure FormAufrufen (aPersonen: THPLPersonen); end; var frmAufgerufen: TfrmAufgerufen; implementation {$R *.dfm} { TfrmAufgerufen } class procedure TfrmAufgerufen.FormAufrufen(aPersonen: THPLPersonen); begin with TfrmAufgerufen.Create(NIL) do try FPersonenKopie:= aPersonen; EditFelderFuellen; if ShowModal= mrOk then begin aPersonen:= FPersonenKopie; end; finally free; end; end; procedure TfrmAufgerufen.EditFelderFuellen; begin edVorName.Text:= FPersonenKopie.VorName; edNachName.Text:= FPersonenKopie.NachName; end; procedure TfrmAufgerufen.btOKClick(Sender: TObject); begin FPersonenKopie.VorName:= edVorName.Text; FPersonenKopie.NachName:=edNachName.Text; end; end. Die Bezeichnungen sollten hoffentlich selbsterklärend sein. Bis bald Chemiker |
Re: Konzeptfrage FormCreate
Hallo Chemiker,
vielen Dank für dein Beispiel... wird heute meine "Zuglektüre" :) Mein Vorhaben ist, mehrere Forms (Anzahl wächst stetig) dynamisch auf einem Panel der Hauptform einzubetten. Es sollen quasi je nach Auswahl in einem Menu die zugehörigen Module angezeigt werden. Um nun nicht jedesmal den gleichen Code beim Aufruf des Moduls aufzuführen, suchte ich nach einer Funktion, welcher ich die entsprechenden Parameter übergeben kann um so bei der Fallunterscheidung nur noch je 1 Zeile Code zu haben. |
Re: Konzeptfrage FormCreate
Zitat:
Erstellung irgendwo in deinem Mainform wie folgt - hab ma der Einfachheit halber auf sämtliches Exceptionhandling verzichtet und alles in eine Zeile gehauen :)
Delphi-Quellcode:
TMyFrame.Create(Self).Parent := MyPanel;
|
Re: Konzeptfrage FormCreate
Welchen Vorteil hat denn die Verwendung von Frames gegenüber Forms im konkreten Fall?
|
Re: Konzeptfrage FormCreate
Forms sind normalerweise als eigenes Window gedacht, und eher sekundär, um sie in ein anderes Control einzubetten, dafür gibt es Frames. Nachteil von Frames ist hingegen, dass sie einige Events nicht haben, wie OnShow etc.
Bei dir handelt es sich - wie ich verstanden habe - um eine Art Control-Sammlung die du abhängig von der Aktion in deinem Programm einzeigst und die nicht als eigenständiges Window existiert, daher würde ich zu einem Frame raten. Solltest du diese Frames dennoch als eigenständiges Fenster einzeigen wollen, könntest du ein Standard-Dialog Fenster erstellen (mit Ok und Cancel Button und was du noch brauchst) und dort dann den Frame als Content einbetten. Weitere Infos: ![]() |
Re: Konzeptfrage FormCreate
Vielen Dank für den Link..
Die fehlenden Events (besonders Create und Destroy) könnten mir zum Verhängnis werden... Aber konnte das Ganze bisher nur überfliegen.... lese es mir gleich nochmal genauer durch... |
Re: Konzeptfrage FormCreate
Letztendlich kann man aber auch jedes fehlende Event noch selber nachträglich einbringen.
|
Re: Konzeptfrage FormCreate
Klar, die Frage ist jedoch, ob es dann noch Vorteile bringt, Frames zu verwenden (offentlich wird das jetzt nicht OT)
|
Re: Konzeptfrage FormCreate
Wie ich aus der Diskussion herausgelesen habe sind Frames eben dafür gedacht, zumal sie zur Laufzeit wie auch zur Designzeit auf die Form eingebettet werden können. Und es bringt nicht nur Vorteile. Das Problem ist eher, das Forms als Child-Windows eher Probleme bringen.
Edit: Ob das OT wird? Naja, es geht hier doch lt. Überschrift um ein Designkonzept. Evtl. müsste dann der Thread noch verschoben werden. |
Re: Konzeptfrage FormCreate
Ich habe mich zugegebenermaßen mit Frames bisher nicht beschäftigt (sollte ich mal nachholen).
Als "Laie" sehe ich derzeit keine Unterschied zwischen der Nutzung einer Form bzw. eines Frames im konkreten Fall. Meine Forms werden zu Laufzeit erzeugt und bekommen als Parent ein Panel auf der Hauptform. Beim Modulwechsel werden alle offenen Formen (außer der Hauptform) geschlossen (was dann geregelt ja nur eine sein dürfte). |
Re: Konzeptfrage FormCreate
Hallo,
@WIng2005: warum nimmst Du nicht das Ereignis OnCreate. DoppelKlick im Objektinspektor erzeugt eine FormCreate Methode. Wenn ich FormCreate aus irgendeinemGrunf nicht verwenden will, schreibe ich einen geöhnlichen Create Konstruktor. So verstehe ich den Sinn Deiner Überlegungen nicht wirklich. Die CreateFormMethode existiert in der Applikation Klasse auch schon. |
Re: Konzeptfrage FormCreate
Mmmh, ich glaube du verstehst das falsch...
Es ging drum, welchen Vorteil Frames gegenüber Forms in meinem Fall hätten. Die OnCreate-Methode gibt es nicht bei Frames, weswegen ich erstmal bei meinen Forms bleibe... |
Re: Konzeptfrage FormCreate
Zitat:
(genau genommen haben wir da noch mehrere Zwischenstufen). Klappt alles hervorragend. |
Re: Konzeptfrage FormCreate
Muss das Thema nochmal aufgreifen.
Zu besseren Übersicht nochmal mein bisheriger Code:
Delphi-Quellcode:
Ist es nun möglich, dass Ganze so abzuändern, dass ich den Aufruf mit
.
. if createform(TForm2,TForm(Form2)) then //machwas; . . function createform(fclass:TFormClass;var nform:Tform):boolean; Begin try application.CreateForm(fclass,nform); nform.Align:=alClient; nform.BorderStyle:=bsNone; nform.Parent:=mainform.panel_df; nform.Show; result:=true; except result:=false; end; end;
Delphi-Quellcode:
starten kann? Versuche schon den ganzen Tag hier mit irgendwelchen Typumwandlungen ans Werk zu gehen, prinzipiell fehlt mir jedoch der Ansatz. Ich dachte, ich könnte so das Zusammenspiel zwischen "Sender" und Form in meiner Button_Click-Routine in eine ini auslagern. (Vllt. ist das auch absolut nicht zu empfehlen, dann lasse ich mich gern belehren)
var a,b:string;
a:='TForm2'; b:='Form2' createform(a,b); |
Re: Konzeptfrage FormCreate
Zitat:
|
Re: Konzeptfrage FormCreate
Mmmh, Die Frames / Forms -Frage hatte sich erstmal erledigt. Forms haben nebenbei auch den Vorteil, dass man sie durchaus mal lösgelöst von der Mainform starten kann. Wichtiger wäre mir erstmal meine vorherige Frage ( 2 Posts weiter oben)
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:02 Uhr. |
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