Mehrere geöffnete Formulare
-
- Beiträge: 845
- Registriert: Sa 12. Sep 2015, 12:10
- OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
- CPU-Target: Win 32/64, Linux64
- Wohnort: Wien
Re: Mehrere geöffnete Formulare
nur meine 2cents....
Die Möglichkeit einer TStringlist Objekte aufzudrücken gibt es schon aus den Anfängen der Delphi-Zeiten. Außer etwas selbst gestricktem gab es damals nix.
Das Problem mit dem Speichern von Objekten/Pointern in Stringlisten ist IMHO dass man sehr gut aufpassen muß dass man keine Speicherleichen produziert wenn der Listeneintrag gelöscht wird aber das Objekt noch existiert. Das wird meines Wissens nicht automatisch von der Klasse erledigt.
Seit 2002 gibt es eben TFPObjektlist, die tatsächlich nur Objekte verwaltet und diese Problem nicht hat
By default it also manages the objects: when an object is deleted or removed from the list, it is automatically freed.
Funktionieren wird sicher beides. Have Fun
Die Möglichkeit einer TStringlist Objekte aufzudrücken gibt es schon aus den Anfängen der Delphi-Zeiten. Außer etwas selbst gestricktem gab es damals nix.
Das Problem mit dem Speichern von Objekten/Pointern in Stringlisten ist IMHO dass man sehr gut aufpassen muß dass man keine Speicherleichen produziert wenn der Listeneintrag gelöscht wird aber das Objekt noch existiert. Das wird meines Wissens nicht automatisch von der Klasse erledigt.
Seit 2002 gibt es eben TFPObjektlist, die tatsächlich nur Objekte verwaltet und diese Problem nicht hat
By default it also manages the objects: when an object is deleted or removed from the list, it is automatically freed.
Funktionieren wird sicher beides. Have Fun
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1436
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
Re: Mehrere geöffnete Formulare
OK, das habe ich dann überlesen. Aber auch beim Formular-Namen ist genau das das Problem: Der Programmierer muss sich peinlich genau darum kümmern, dass der Formularname nicht irgendwo schon vergeben ist, sonst freut sich der User über einen Absturz. Daher würde ich eher dazu raten, den Wert von Screen.Forms[...] in das Objekt der ListView-Items zu packen, so wie von dir schon vorgeschlagen. Da muss man sich nicht um doppelte Namen kümmern.fliegermichl hat geschrieben: ↑Mi 17. Feb 2021, 15:25Es ging doch um den Komponentennamen. Der kann nicht doppelt sein (ausser wenn er leer ist)
-
- Beiträge: 202
- Registriert: Mo 24. Aug 2020, 14:16
- OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
- CPU-Target: i386
Re: Mehrere geöffnete Formulare
TStringList hat eine Eigenschaft OwnsObjects, die ebenfalls das Freigeben der Objekte bei Operationen wie Clear oder Delete bewirkt. Ob man sie hier einsetzt, ist eine andere Frage.
Ich hatte das seinerzeit so gelöst, dass ich die jeweilige (natürlich möglichst aussagekräftige und vor allem eindeutige wie zB Kundennummer / Name) Caption des Formulars sowie sowie das Form selbst (bzw den Pointer darauf als Object) in einer StringList gespeichert habe. Im MainMenu des Hauptformulars hatte ich einen Eintrag 'Fenster', in dessen OnClick ich die Captions als Untereinträge hinzugefügt habe. In deren OnClick wiederum das passende Object sprich Form der StringList, zB über Index, heraussuchen und mit Show / BringToFront etc anzeigen. Die Verwaltung der Liste kann dann zB in OnClose der jeweiligen Formulare erfolgen - Eintrag löschen wieder über IndexOf - und das Hinzufügen natürlich an der Stelle, wo die Forms erzeugt werden. Dort auch die Behandlung eventueller Duplikate - wenn ein User zB eine Adresse aufrufen will, für die schon ein Form existiert, kann man nachfragen, ob dies nach vorne gebracht oder eine neue Instanz zB mit Zusatz '(2)' geöffnet werden soll. Nur mal als grobe Skizze.
Ich hatte das seinerzeit so gelöst, dass ich die jeweilige (natürlich möglichst aussagekräftige und vor allem eindeutige wie zB Kundennummer / Name) Caption des Formulars sowie sowie das Form selbst (bzw den Pointer darauf als Object) in einer StringList gespeichert habe. Im MainMenu des Hauptformulars hatte ich einen Eintrag 'Fenster', in dessen OnClick ich die Captions als Untereinträge hinzugefügt habe. In deren OnClick wiederum das passende Object sprich Form der StringList, zB über Index, heraussuchen und mit Show / BringToFront etc anzeigen. Die Verwaltung der Liste kann dann zB in OnClose der jeweiligen Formulare erfolgen - Eintrag löschen wieder über IndexOf - und das Hinzufügen natürlich an der Stelle, wo die Forms erzeugt werden. Dort auch die Behandlung eventueller Duplikate - wenn ein User zB eine Adresse aufrufen will, für die schon ein Form existiert, kann man nachfragen, ob dies nach vorne gebracht oder eine neue Instanz zB mit Zusatz '(2)' geöffnet werden soll. Nur mal als grobe Skizze.
Re: Mehrere geöffnete Formulare
Das ist ja der Jammer. Ich krieg es ja nicht mal auf die Reihe ordentlich zu prüfen ob ein Formular geöffnet ist oder nicht.
Habs mal so versucht.
Code: Alles auswählen
if not Assigned(Frm_DATEN_IMPORT_PERSONAL) then
begin
Application.CreateForm(TFrm_DATEN_IMPORT_PERSONAL , Frm_DATEN_IMPORT_PERSONAL );
Frm_DATEN_IMPORT_PERSONAL.Height := FENSTER_PANEL.Height;
Frm_DATEN_IMPORT_PERSONAL.left := left + FENSTER_PANEL.left;
Frm_DATEN_IMPORT_PERSONAL.Top := Top + FENSTER_PANEL.top;
with ListView1.Items.Add do
begin
Caption := 'IMPORT PERSONAL DATEN';
SubItems.Add('Frm_DATEN_IMPORT_PERSONAL');
end;
Frm_DATEN_IMPORT_PERSONAL.show;
end;
Code: Alles auswählen
for i := 0 to Frm_A_MAIN_HAUPTMENU.ListView1.Items.Count - 1 do
if Frm_A_MAIN_HAUPTMENU.ListView1.Items[i].Caption = 'IMPORT PERSONAL DATEN' then
begin
Frm_A_MAIN_HAUPTMENU.ListView1.Items.Delete(i);
break;
end;
inherited;
CloseAction := caFree;
Nur wenn ich es erneut öffenen möchte, dann passiert gar nichts.
Anscheinend ist das Form immer noch assigned...
Warum ? ich versteh es nicht.
Dieses Formhandling treibt mich noch in den Wahnsinn
Re: Mehrere geöffnete Formulare
..macht mich fertig, ehrlich
FreeAndNill(Form) funktioniert nicht
aber
inherited;
CloseAction := caFree;
Frm_DATEN_IMPORT_PERSONAL := Nil;
Kann man ganz schön verzeifeln ehrlich...
FreeAndNill(Form) funktioniert nicht
aber
inherited;
CloseAction := caFree;
Frm_DATEN_IMPORT_PERSONAL := Nil;
Kann man ganz schön verzeifeln ehrlich...
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Mehrere geöffnete Formulare
Hi!
Diesen Kladderadatsch hatte ich geahnt und deshalb empfohlen, im Gleichklang mit Lazarus zu arbeiten:
Wenn es nicht die Haupt-Form ist, dann bedeutet
das Gleiche wie
Funktioniert alles wunderbar.
Warum verlässt Du Dich nicht darauf?
Winni
Diesen Kladderadatsch hatte ich geahnt und deshalb empfohlen, im Gleichklang mit Lazarus zu arbeiten:
Wenn es nicht die Haupt-Form ist, dann bedeutet
Code: Alles auswählen
Form123.close
Code: Alles auswählen
Form123.hide
Warum verlässt Du Dich nicht darauf?
Winni
-
- Beiträge: 845
- Registriert: Sa 12. Sep 2015, 12:10
- OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
- CPU-Target: Win 32/64, Linux64
- Wohnort: Wien
Re: Mehrere geöffnete Formulare
kann es sein dass dein Formular Frm_DATEN_IMPORT_PERSONAL von Lazarus selbst erstellt wird?
Mir kommt vor als ob du die Lazarus(IDE)-Internen Möglichkeiten des Formhandlings (also solche Sachen wie CloseAction := caFree; mit selbst aus dem Code erstellten Formularen mischt.
Kann durchaus sein dass ich mit meiner Vermutung völlig falsch liege.
In meinen Projekteinstellungen (Project Options - Forms) wird mittlerweile nur mehr das Hauptformular automatisch generiert. Alle anderen Formulare und Objekte generiere ich im Code und sorge auch für deren Freigabe.
Allerdings verwende ich NICHT die im Formular von Lazarus mit eingebaute allgemeine Variable
sondern erstelle mir das Formular selbst. Und zwar nicht IM Formular sondern von außerhalb des Formulars -- also in der Navigation, im Menü oder irgendwo im Programm. folgender Code steht zB in einem Menüpunkt oder einem Doppelklickevent einer Liste
Dann kann ich jederzeit von innerhalb (zB mittels einem auf dem Formular befindlichen Knopf) oder von außerhalb das Formular sauber schließen und freigeben.
Anders gesagt, ich benutze die Formulare als nur Klassen und erzeuge die nötigen Objekte selbst.
Ich weiß es gibt viele Varianten wie man so etwas angehen kann aber ich vermeide wo es nur geht von einem Formular auf ein anderes undefiniert zuzugreifen.
Die Fensterobjekte verwalte ich in einer eigenen globalen Liste und aus die Maus.
Aber möglicherweise bin ich nur Oldfashioned
Mir kommt vor als ob du die Lazarus(IDE)-Internen Möglichkeiten des Formhandlings (also solche Sachen wie CloseAction := caFree; mit selbst aus dem Code erstellten Formularen mischt.
Kann durchaus sein dass ich mit meiner Vermutung völlig falsch liege.
In meinen Projekteinstellungen (Project Options - Forms) wird mittlerweile nur mehr das Hauptformular automatisch generiert. Alle anderen Formulare und Objekte generiere ich im Code und sorge auch für deren Freigabe.
Allerdings verwende ich NICHT die im Formular von Lazarus mit eingebaute allgemeine Variable
Code: Alles auswählen
var
Frm_DATEN_IMPORT_PERSONAL: TFrm_DATEN_IMPORT_PERSONAL;
Code: Alles auswählen
var
myWnd:TfrmKunde;
begin
myWnd := TfrmKunde.Create(Nil);
//alles was das Formular von außen braucht bekommt es als Properities übergeben
//direkte Referenzen auf andere Formulare gibt es nicht.
myWnd.Tag:= iTag;
myWnd.piKdID:=rKunde.kdid; //Diverse IDs setzen
myWnd.piID:=rKunde.kdid; //die ID setzen
myWnd.piFormtype:=ciWKUNDE; //Typ des Fensters setzen
//als Public definierte Prozeduren kann man von außen aufrufen
//Initialisiert das Fenster, schreibt Captions, befüllt das Fenster mit Daten etc etc
myWnd.Initialize;
//ggfs das Formular irgendwo eindocken
myWnd.ManualDock(<irgendein Dockingziel>, NIL, alClient);
//ggfs das Formularobjekt in einer Liste verwalten
Add(myWnd,3); //hängt das gerade erzeugte Fenster in die Fensterliste ein
//und dann anzeigen
myWnd.Show; //oder auch showmodal
Anders gesagt, ich benutze die Formulare als nur Klassen und erzeuge die nötigen Objekte selbst.
Ich weiß es gibt viele Varianten wie man so etwas angehen kann aber ich vermeide wo es nur geht von einem Formular auf ein anderes undefiniert zuzugreifen.
Die Fensterobjekte verwalte ich in einer eigenen globalen Liste und aus die Maus.
Aber möglicherweise bin ich nur Oldfashioned
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Mehrere geöffnete Formulare
Hallo!
Ganz einfache Lösung, die sich aber darauf verlässt, dass Du den Lazarus-Weg bzgl. der Forms gehst, und nicht wild und eigenhändig dauernd Formen createst und destroys:
Winni
Ganz einfache Lösung, die sich aber darauf verlässt, dass Du den Lazarus-Weg bzgl. der Forms gehst, und nicht wild und eigenhändig dauernd Formen createst und destroys:
Code: Alles auswählen
procedure TForm1.Test1Click(Sender: TObject);
var i : integer;
sl: TStringList;
s : string;
begin
sl := TStringList.create;
for i := 0 to Screen.FormCount- 1 do
begin
s := Screen.Forms[i].name+#32;
if Not Screen.Forms[i].visible then s := s+'not ';
s := s + 'visible';
sl.add (s);
end;
showMessage (sl.text);
// Hier sl z.B. einer ListBox zuweisen
sl.free;
end;
Winni
Re: Mehrere geöffnete Formulare
Die Formularvariable Frm_DATEN_IMPORT_PERSONAL ist wahrscheinlich irgendwo global angelegt. Wenn du jetzt dieses Formular schließt und hast im OnClose-Event den Befehl CloseAction := caFree, dann wird das Formular tatsächlich zerstört. Aber deine Formularvariable kriegt davon nichts mit und bleibt unverändert (d.h. <> nil), zeigt natürlich auf nicht mehr allokierten Speicher und würde dein Programm crashen lassen, wenn du sowas wie Frm_DATEN_IMPORT_PERSONAL.Show aufrufen würdest.Bernie110 hat geschrieben: ↑Mi 17. Feb 2021, 16:32Der Witz ist, ich kann das Form öffnen und schliessen. Alles gut..
Nur wenn ich es erneut öffenen möchte, dann passiert gar nichts.
Anscheinend ist das Form immer noch assigned...
Warum ? ich versteh es nicht.
Dieses Formhandling treibt mich noch in den Wahnsinn
Wenn du jetzt das Formular ein zweites Mal erzeugen möchtest, so hat dein Code zu Beginn die Anweisung "if not Assigned(Frm_DATEN_IMPORT_PERSONAL)" und diese Bedingung ist nicht erfüllt, weil du beim Schließen des Formulars die Variable nicht auf nil gesetzt hast. Du hast Glück, dass nach dem "if" nicht mehr auf die Formularvariable zugegriffen wird. Würdest du "Frm_DATEN_IMPORT_PERSONAL.Show" aus dem if-Block herausnehmen, gäb's hier 'nen Crash.
Welche Lösungen gibt es?
(1) Wenn du das Formular ohnehin mehrfach aufrufen willst, wäre es einfacher, es gar nicht zu zerstören, sondern nur zu verstecken. Das ist sowie die Standard-Aktion beim Schließen eines Formulas, wenn man keine CloseAction angibt. Aber das hat winni schon geschrieben.
(2) Wenn du bei CloseAction = caFree bleiben willst, muss das Formular, das Frm_DATEN_IMPORT_PERSONAL erzeugt hat, den OnClose-Handler zur Verfügung stellen und dort die Formular-Variable auf nil setzen:
Code: Alles auswählen
procedure TMainForm.Frm_DATEN_IMPORT_PERSONALClose(Sender: TObject; var CloseAction: TCloseAction);
begin
CloseAction := caFree;
Frm_DATEN_IMPORT_PERSONAL := nil;
end;
procedure TMainForm.CreateFrm_DATEN_IMPORT_PERSONAL.Show;
begin
if not Assigned(Frm_DATEN_IMPORT_PERSONAL) then
begin
Application.CreateForm(TFrm_DATEN_IMPORT_PERSONAL , Frm_DATEN_IMPORT_PERSONAL );
Frm_DATEN_IMPORT_PERSONAL.Height := FENSTER_PANEL.Height;
Frm_DATEN_IMPORT_PERSONAL.left := left + FENSTER_PANEL.left;
Frm_DATEN_IMPORT_PERSONAL.Top := Top + FENSTER_PANEL.top;
Frm_DATEN_IMPORT_PERSONAL.OnClose := @Frm_DATEN_IMPORT_PERSONALClose; // <----- !!!!
with ListView1.Items.Add do
begin
Caption := 'IMPORT PERSONAL DATEN';
SubItems.Add('Frm_DATEN_IMPORT_PERSONAL');
end;
end;
Frm_DATEN_IMPORT_PERSONAL.show;
end;
Re: Mehrere geöffnete Formulare
Hallo Zusammen, danke für eure Antworten.
Wenn du das meinst.
Mag sein dass dies der falsche Weg ist und entgegen einiger ClassenModulregeln widerspricht.
Jedoch ist es mir ehrlich gesagt viel zu viel arbeit alles per Code zu generieren.
Bis ein Formular bei mir fertig ist, dauert mir schon viel zu lange.
Was ich jedoch schon mache ist, wenn ein Fomular lediglich nur Suchfelder und ein DBGrid enthält
es mehrfach zu nutzen. Heisst, dass Grid flexibel auch mit anderen Daten zu befüllen und den Style auf die
jeweilige Anforderung anzupassen.
Erfassungsmasken haben eigentlich alle ein eigenes Formular.
nur mit Show und ohne destroy zuöffnen.
Hier hat man mir dann gesagt, dass es falsch ist. Formulare sollten nach Gebrauch immer zerstört werden, da sonst
irgendwann Speicherlags entstehen.
In meinem aktuellem Programm wird jedes Forumular mit create erstellt und mit cafree wieder zerstört. ( Ausser das Hauptmenu)
Solange man Showmodal benutzt ist das auch nicht sehr aufwendig.
Benutzt man aber nur Show.... weil man gleichzeitig auch in anderen Formularen arbeiten möchte.....tja
Das finde ich auch irgendwie nicht gut gelöst.
Die Ausnahme ist bei mir, dass ich "hide" brauche.
Ich habs ja jetzt so gelöst wie du es vorschlägst.
Funktioniert auch nun alles.
Ob das so alles richtig ist und welche Probleme daraus wieder entstehen, wird sich zeigen
Mit der Erfahrung wächst eben die Fähigkeit es besser zu machen...sehe ich ziemlich sportlich ....
also kein Problem
Danke @ all. Ihr habt mir wie immer sehr geholfen !!!
Lg Bernie
Hi, nein. Das Formular ist bereits genau so zusammengebaut wie es zur Laufzeit auch aussehen soll.charlytango hat geschrieben: ↑Mi 17. Feb 2021, 19:58kann es sein dass dein Formular Frm_DATEN_IMPORT_PERSONAL von Lazarus selbst erstellt wird?
Wenn du das meinst.
Mag sein dass dies der falsche Weg ist und entgegen einiger ClassenModulregeln widerspricht.
Jedoch ist es mir ehrlich gesagt viel zu viel arbeit alles per Code zu generieren.
Bis ein Formular bei mir fertig ist, dauert mir schon viel zu lange.
Was ich jedoch schon mache ist, wenn ein Fomular lediglich nur Suchfelder und ein DBGrid enthält
es mehrfach zu nutzen. Heisst, dass Grid flexibel auch mit anderen Daten zu befüllen und den Style auf die
jeweilige Anforderung anzupassen.
Erfassungsmasken haben eigentlich alle ein eigenes Formular.
Hi winni. Als ich vor einem Jahr mit Lazarus anfing waren in meinem ersten Programm alle Formulare
nur mit Show und ohne destroy zuöffnen.
Hier hat man mir dann gesagt, dass es falsch ist. Formulare sollten nach Gebrauch immer zerstört werden, da sonst
irgendwann Speicherlags entstehen.
In meinem aktuellem Programm wird jedes Forumular mit create erstellt und mit cafree wieder zerstört. ( Ausser das Hauptmenu)
Solange man Showmodal benutzt ist das auch nicht sehr aufwendig.
Benutzt man aber nur Show.... weil man gleichzeitig auch in anderen Formularen arbeiten möchte.....tja
Das finde ich auch irgendwie nicht gut gelöst.
Die Ausnahme ist bei mir, dass ich "hide" brauche.
Aha... ich stell mir gerade die Frage wo das sein soll ?
Ich habs ja jetzt so gelöst wie du es vorschlägst.
Funktioniert auch nun alles.
Ob das so alles richtig ist und welche Probleme daraus wieder entstehen, wird sich zeigen
Mit der Erfahrung wächst eben die Fähigkeit es besser zu machen...sehe ich ziemlich sportlich ....
also kein Problem
Danke @ all. Ihr habt mir wie immer sehr geholfen !!!
Lg Bernie
- af0815
- Lazarusforum e. V.
- Beiträge: 6218
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: Mehrere geöffnete Formulare
Man kann die Wege auch verschieden nutzen, nur den Weg sollte man verstehen und auch beibehalten.
Erstelle ich ein Formular selbst, dann kann ich die Lebenszeit bestimmen. Punkt. Brauche ich das Formular öfters im Programm, dann bleibt es im Hintergrund und wird nicht freigegeben. Wenn ich es freigebe, so setze ich die Variable, die das Formular hält auf nil.
Brauche ich ein Formular nur selten, so wird es nach der Verwendung wieder zerstört und auch auf nil gesetzt.
Man kann sich auch ein paar Basisformulare schaffen, wo zB. gerade die Anbindung an die Datenbanken gleich ist, ich rede nicht von den Queries und vererbe das an Formulare. Damit habe ich gemeinsamen Code an einer STelle und beim Bugfixen brauche ich nur eine Stelle fixen und nicht 50, wo ich garantiert 1-2 vergesse.
Dasselbe mache ich auch mit Frames. die ich gerne verwende um Visualisierung und Code zur Visualisierung kapsle. Damit sind auch die Daten gekapselt. Jedes Frame lässt sich so in einer Testumgebung sehr gut testen und anschliessend einfach in die Applikation einhängen. Und auch hier kann man Vererbung sehr viel an gemeinsamen Code zusammenfassen.
Generell halte ich es so, das NUR das Hauptformular erzeugt wird. Im OnCreate werden die Variablen initialisiert und alles weitere beim ersten mal OnActivate gemacht. Auch Datenmodule, Formulare, Frames etc. werden hier erstellt. Warum das ganze (seit Delphi 5 erprobt). Hier im OnActivate ist der erste Zeitpunkt wo du sicher bist, das ALEES erstellt ist. Auch das was Lazarus für dich automatisch baut und zusätzlich weis ich genau, was ich wo, in welcher Reihenfolge benötige. Weil mir hat schon oft der Editor einen Streich gespielt und mal die erzeugten Forulare zurückgesetzt, wenn du dann einfach alle wieder auf automatisch erstellst setzt, hast du unter Umständen eine nicht funktionierende App. So fällt es mir sofort auf, das das Formular nicht erscheint. Ich öffne die Projektoptionen und setze das Hauptformular wieder auf automatisch. Da brauche ich nicht weiter nachzudenken.
Erstelle ich ein Formular selbst, dann kann ich die Lebenszeit bestimmen. Punkt. Brauche ich das Formular öfters im Programm, dann bleibt es im Hintergrund und wird nicht freigegeben. Wenn ich es freigebe, so setze ich die Variable, die das Formular hält auf nil.
Brauche ich ein Formular nur selten, so wird es nach der Verwendung wieder zerstört und auch auf nil gesetzt.
Man kann sich auch ein paar Basisformulare schaffen, wo zB. gerade die Anbindung an die Datenbanken gleich ist, ich rede nicht von den Queries und vererbe das an Formulare. Damit habe ich gemeinsamen Code an einer STelle und beim Bugfixen brauche ich nur eine Stelle fixen und nicht 50, wo ich garantiert 1-2 vergesse.
Dasselbe mache ich auch mit Frames. die ich gerne verwende um Visualisierung und Code zur Visualisierung kapsle. Damit sind auch die Daten gekapselt. Jedes Frame lässt sich so in einer Testumgebung sehr gut testen und anschliessend einfach in die Applikation einhängen. Und auch hier kann man Vererbung sehr viel an gemeinsamen Code zusammenfassen.
Generell halte ich es so, das NUR das Hauptformular erzeugt wird. Im OnCreate werden die Variablen initialisiert und alles weitere beim ersten mal OnActivate gemacht. Auch Datenmodule, Formulare, Frames etc. werden hier erstellt. Warum das ganze (seit Delphi 5 erprobt). Hier im OnActivate ist der erste Zeitpunkt wo du sicher bist, das ALEES erstellt ist. Auch das was Lazarus für dich automatisch baut und zusätzlich weis ich genau, was ich wo, in welcher Reihenfolge benötige. Weil mir hat schon oft der Editor einen Streich gespielt und mal die erzeugten Forulare zurückgesetzt, wenn du dann einfach alle wieder auf automatisch erstellst setzt, hast du unter Umständen eine nicht funktionierende App. So fällt es mir sofort auf, das das Formular nicht erscheint. Ich öffne die Projektoptionen und setze das Hauptformular wieder auf automatisch. Da brauche ich nicht weiter nachzudenken.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Mehrere geöffnete Formulare
Hi!Bernie110 hat geschrieben: ↑Do 18. Feb 2021, 08:16
Hi winni. Als ich vor einem Jahr mit Lazarus anfing waren in meinem ersten Programm alle Formulare
nur mit Show und ohne destroy zuöffnen.
Hier hat man mir dann gesagt, dass es falsch ist. Formulare sollten nach Gebrauch immer zerstört werden, da sonst
irgendwann Speicherlags entstehen.
Also aus Speichermangel die Formulare mit destroy zu zertören, ist heutzutage völliger Blödsinn, wo wir alle mindestens 16 oder 32 GB RAM besitzen. Das höhrt sich nach Delphi-Weisheiten von 1995 an, als RAM sehr teuer war - insbesondere nach dem Erdbeben in Japan, als die RAM-Chip-Fabrik in Kobe ein Totalschaden war,
Und wer immer Dir diesen Tip gegeben hat, hat nicht verstanden wir Lazarus die Formulare verwaltet. Ein Blick in eine lpr mit mehreren Formularen hilft auf die Schnelle schon mal weiter:
Code: Alles auswählen
...
RequireDerivedFormResource:=True;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.CreateForm(TForm3, Form3);
Application.CreateForm(TForm4, Form4);
Application.Run;
...
Einfach anfangen, und wenn es läuft, kann man es immer noch "verschlimmbessern!"
Winni
Re: Mehrere geöffnete Formulare
Wenn du's nicht weißt, wie soll ich das wissen? Im Ernst: Wenn du eine neue Unit für das die Formularklasse Tfrm_DATEN_IMPORT_PERSONAL erzeugst, steht im Interface-Teil unter der type Deklaration immer der Name der automatisch generierten Formular-variablen:
Code: Alles auswählen
type
Tfrm_DATEN_IMPORT_PERSONAL = class(TForm)
...
end;
var
frm_DATEN_IMPORT_PERSONAL: Tfm_DATEN_IMPORT_PERSONAL;
Re: Mehrere geöffnete Formulare
Hallo Zusammen,
Danke für eure Antworten.
Es ist jetzt für mich nun verständlicher.
@ Winni du hast Recht. Ich hader damit wohl zuviel. Hauptgrund ist eben zu wenig Erfahrung.
Kommt schon noch
@ wp_xyz
Die Lösung war das Formular := Nil bei Close zusetzten.
Ich dachte CaFree würde ausreichen...
Lg Bernie
Danke für eure Antworten.
Es ist jetzt für mich nun verständlicher.
@ Winni du hast Recht. Ich hader damit wohl zuviel. Hauptgrund ist eben zu wenig Erfahrung.
Kommt schon noch
Alles klar. So werd ich ab jetzt auch machen.Erstelle ich ein Formular selbst, dann kann ich die Lebenszeit bestimmen. Punkt. Brauche ich das Formular öfters im Programm, dann bleibt es im Hintergrund und wird nicht freigegeben. Wenn ich es freigebe, so setze ich die Variable, die das Formular hält auf nil.
@ wp_xyz
Und genau darin steht es nicht. Darin befindet sich nur das Hauptformular. Daher meine Frage wie das sein könnte.Ein Formular mit diesem Namen wird automatisch beim Start der Anwendung erzeugt, wenn es in den Projekt-Optionen > Formulare in der Liste der "Automatisch erzeugten Formulare" steht.
Die Lösung war das Formular := Nil bei Close zusetzten.
Ich dachte CaFree würde ausreichen...
Lg Bernie