[ Gelöst ] Application.CreateForm(...
- Niesi
- Lazarusforum e. V.
- Beiträge: 587
- Registriert: So 26. Jun 2016, 19:44
- OS, Lazarus, FPC: Linux Mint Cinnamon, Laz 4.1 Fpc 3.2.3 und allerlei mit FpcUpDeLuxe
- Kontaktdaten:
[ Gelöst ] Application.CreateForm(...
Hallo,
ich habe da eine Verständnisfrage (eigentlich versuche ich was ganz anderes zu verstehen, ein Problem in der Pdfium, aber da sprang mich was an):
Wenn ich einem Projekt eine Unit mit Form zuweise, dann wird in der lpr automatisch ein Application.CreateForm(... erzeugt. Trotzdem muss ich in meinem MainForm den InfoForm mit
"MyInfoForm := tMyInfoForm.Create(Self);"
erzeugen, sonst gibt's einen SIGSEGV.
Warum das denn? Die Form ist doch da, existiert, oder?
Gleichzeitig darf ich in Destructor meiner MainForm die MyInfoForm aber nicht mit Free freigen, denn sonst gibt es zum Abschluss einen SIGSEGV.
Kommentiere ich in der lpr das "Application.CreateForm(TMyInfoForm, MyInfoForm);" aus, so läuft alles so, wie ich es von der Logik her erwartet habe.
Weiß wer, warum ich ich trotz "Application.CreateForm(TMyInfoForm, MyInfoForm);" in der lpr noch den MyInfoForm in meinem Constructor erzeugen muss, ihn dann aber nicht "destroyen" darf?
Ich hänge mein Beispiel mal hier ran, falls mein Text nicht verständlich genug ist - wie geschrieben, ich suchte eigentlich andere Antworten, daher ist da noch anderes Zeugs dabei ...
ich habe da eine Verständnisfrage (eigentlich versuche ich was ganz anderes zu verstehen, ein Problem in der Pdfium, aber da sprang mich was an):
Wenn ich einem Projekt eine Unit mit Form zuweise, dann wird in der lpr automatisch ein Application.CreateForm(... erzeugt. Trotzdem muss ich in meinem MainForm den InfoForm mit
"MyInfoForm := tMyInfoForm.Create(Self);"
erzeugen, sonst gibt's einen SIGSEGV.
Warum das denn? Die Form ist doch da, existiert, oder?
Gleichzeitig darf ich in Destructor meiner MainForm die MyInfoForm aber nicht mit Free freigen, denn sonst gibt es zum Abschluss einen SIGSEGV.
Kommentiere ich in der lpr das "Application.CreateForm(TMyInfoForm, MyInfoForm);" aus, so läuft alles so, wie ich es von der Logik her erwartet habe.
Weiß wer, warum ich ich trotz "Application.CreateForm(TMyInfoForm, MyInfoForm);" in der lpr noch den MyInfoForm in meinem Constructor erzeugen muss, ihn dann aber nicht "destroyen" darf?
Ich hänge mein Beispiel mal hier ran, falls mein Text nicht verständlich genug ist - wie geschrieben, ich suchte eigentlich andere Antworten, daher ist da noch anderes Zeugs dabei ...
Zuletzt geändert von Niesi am Mo 18. Nov 2024, 16:43, insgesamt 1-mal geändert.
Wissen ist das einzige Gut, das sich vermehrt, wenn es geteilt wird ...
- af0815
- Lazarusforum e. V.
- Beiträge: 6782
- 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: Application.CreateForm(...
Ich habe mich auch schon sowas mal gefragt - bin damals zu dem Schluss gekommen, das das mit der initialsieren des Applikationsobjektes zusammenhängt, das bei GUIs ja auch das ganze GUI Framework im Hintergrund initialisieren muss. Ausserdem werden zum Beispiel die Messagequece an das erste Form gebunden, weil irgendwer muss ja Botschaften empfangen. Kurzum alles was den Komfort von RAD wird im Hintergrund zugewiesen.
Ist aber schon länger her, weil ich habe damals was mit den Frames gesucht und bin dabei ziemlich tief in die Materie eingetaucht - ohne es zu wollen
----
Entweder du gibst die Kontrolle über das Formular an Lazarus ab - dann Autocreate über die LPR - oder du machst alles selbst, dann kein Eintrag in der LPF und die VAR definition im Infoform kannst du dir sparen (ich lösche die immer, damit ich nicht falsch auf was zugreife).
Edit:
Dein Code geht deswegen nicht, weil du im Create bereits das Info Fenster aufrufst und das ist ja zu diesem Zeitpunkt noch nicht initialisiert (Wäre erste der nächste Schritt im lpr). Man sieht es , wenn man sich den Call Stack ansieht. Dein Problem ist, das du die Reihenfolge auch nicht umdrehen kannst, weil ja das erste Form das "MainForm" ist das mit Run ja auch aufgerufen wird. Deswegen mache ich alle Initialisierunegn und erzeugen von Formularen, DataModulen etc. immer erst im ersten AUfruf von OnActivate, weil dort sind alle bisherigen Creates bereits durch und ich habe die Möglichkeit genau die Lebensdauer zu definieren.
Ist aber schon länger her, weil ich habe damals was mit den Frames gesucht und bin dabei ziemlich tief in die Materie eingetaucht - ohne es zu wollen

----
Entweder du gibst die Kontrolle über das Formular an Lazarus ab - dann Autocreate über die LPR - oder du machst alles selbst, dann kein Eintrag in der LPF und die VAR definition im Infoform kannst du dir sparen (ich lösche die immer, damit ich nicht falsch auf was zugreife).
Code: Alles auswählen
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, infoform;
type
{ TMainForm }
TMainForm = class(TForm)
MyMemo: TMemo;
private
MyInfoForm: TMyInfoForm;
public
constructor Create(aOwner: tComponent); override;
destructor Destroy; override;
end;
Dein Code geht deswegen nicht, weil du im Create bereits das Info Fenster aufrufst und das ist ja zu diesem Zeitpunkt noch nicht initialisiert (Wäre erste der nächste Schritt im lpr). Man sieht es , wenn man sich den Call Stack ansieht. Dein Problem ist, das du die Reihenfolge auch nicht umdrehen kannst, weil ja das erste Form das "MainForm" ist das mit Run ja auch aufgerufen wird. Deswegen mache ich alle Initialisierunegn und erzeugen von Formularen, DataModulen etc. immer erst im ersten AUfruf von OnActivate, weil dort sind alle bisherigen Creates bereits durch und ich habe die Möglichkeit genau die Lebensdauer zu definieren.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 6919
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Application.CreateForm(...
Du machst ein Show von einem Form, das es gar noch nicht gibt.Wenn ich einem Projekt eine Unit mit Form zuweise, dann wird in der lpr automatisch ein Application.CreateForm(... erzeugt. Trotzdem muss ich in meinem MainForm den InfoForm mit
"MyInfoForm := tMyInfoForm.Create(Self);"
erzeugen, sonst gibt's einen SIGSEGV.
Code: Alles auswählen
// MyInfoForm := tMyInfoForm.Create(Self);
MyInfoForm.Show;
Code: Alles auswählen
Application.CreateForm(TMyInfoForm, MyInfoForm);
Application.CreateForm(TMainForm, MainForm);
Was man noch machen kann, überprüfen, ob es nicht nil ist,
Code: Alles auswählen
if MyInfoForm = nil then begin
ShowMessage('nil');
exit;
end;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
- Niesi
- Lazarusforum e. V.
- Beiträge: 587
- Registriert: So 26. Jun 2016, 19:44
- OS, Lazarus, FPC: Linux Mint Cinnamon, Laz 4.1 Fpc 3.2.3 und allerlei mit FpcUpDeLuxe
- Kontaktdaten:
Re: Application.CreateForm(...
Da hast Du Recht - und das ist auch logisch. Weil ich den Constructor überschrieben habe, passt die Reihenfolge in der lpr nicht mehr.Mathias hat geschrieben: So 17. Nov 2024, 14:20Du machst ein Show von einem Form, das es gar noch nicht gibt.Wenn ich einem Projekt eine Unit mit Form zuweise, dann wird in der lpr automatisch ein Application.CreateForm(... erzeugt. Trotzdem muss ich in meinem MainForm den InfoForm mit
"MyInfoForm := tMyInfoForm.Create(Self);"
erzeugen, sonst gibt's einen SIGSEGV.Darum habe ich die Zeilen da vertauscht, und siehe da, es geht auf einmal,Code: Alles auswählen
// MyInfoForm := tMyInfoForm.Create(Self); MyInfoForm.Show;
Code: Alles auswählen
Application.CreateForm(TMyInfoForm, MyInfoForm); Application.CreateForm(TMainForm, MainForm);
Was man noch machen kann, überprüfen, ob es nicht nil ist,Code: Alles auswählen
if MyInfoForm = nil then begin ShowMessage('nil'); exit; end;
Ok. Den Punkt hast Du geklärt. Danke

Bleibt noch die Frage: Warum erzeugt ein MyInfoForm.Free ein SIGSEGV? Irgendwie habe ich abgespeichert, dass bei Free geprüft wird, ob überhaupt etwas destroyed werden kann / muss und es nichts ausmacht, wenn das gar nicht der Fall ist ...
Liege ich da falsch?
Wissen ist das einzige Gut, das sich vermehrt, wenn es geteilt wird ...
-
- Beiträge: 726
- Registriert: Do 27. Sep 2012, 00:07
- OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
- CPU-Target: x86_64-win64
- Wohnort: Hamburg
Re: Application.CreateForm(...
Du benutzt MyInfoForm schon in Constructor von Mainform. Das System noch keine Gelegenheit gehabt MyInfoForm zu erstellen.
Wenn du MyInfoForm später benutzt, z.B. durch Benutzerinteraktion, dann passiert nichts, auch wenn du es in Mainform freigibst passiert nichts.
Noch etwas, die erste Form die man in LPR-Datei mit Application.CreateForm erstellt wird Hauptform (Application.Mainform) und wenn man Hauptform schließt, dann wird das Programm beendet.
Wenn du MyInfoForm später benutzt, z.B. durch Benutzerinteraktion, dann passiert nichts, auch wenn du es in Mainform freigibst passiert nichts.
Noch etwas, die erste Form die man in LPR-Datei mit Application.CreateForm erstellt wird Hauptform (Application.Mainform) und wenn man Hauptform schließt, dann wird das Programm beendet.
- Niesi
- Lazarusforum e. V.
- Beiträge: 587
- Registriert: So 26. Jun 2016, 19:44
- OS, Lazarus, FPC: Linux Mint Cinnamon, Laz 4.1 Fpc 3.2.3 und allerlei mit FpcUpDeLuxe
- Kontaktdaten:
Re: Application.CreateForm(...
Ja, das mit dem Aufruf von MyInfoForm VOR der Erstellung hatte Mathias schon geklärt. Und dass die ertse in der lpr erstellte Form dann die Hauptform ist, das wusste ich noch.Soner hat geschrieben: So 17. Nov 2024, 19:23 Du benutzt MyInfoForm schon in Constructor von Mainform. Das System noch keine Gelegenheit gehabt MyInfoForm zu erstellen.
Wenn du MyInfoForm später benutzt, z.B. durch Benutzerinteraktion, dann passiert nichts, auch wenn du es in Mainform freigibst passiert nichts.
Noch etwas, die erste Form die man in LPR-Datei mit Application.CreateForm erstellt wird Hauptform (Application.Mainform) und wenn man Hauptform schließt, dann wird das Programm beendet.
Was mit fehlt, ist der Grund für den SIGSEGV, wenn ich "MyInfoForm.Free;" aufrufe. Sollte Free nicht so sein, dass das Objekt "destroyed" wird, wenn es noch existiert, aber nichts passiert, wenn es bereits erledigt ist?
Habe ich das falsch im Kopf?
Wissen ist das einzige Gut, das sich vermehrt, wenn es geteilt wird ...
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1647
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
Re: Application.CreateForm(...
Normale globale Variablen sind nicht initialisiert.
D.h. die Form wurde noch nicht erzeugt aber der Variableninhalt ist nicht nil und das sorgt für die Exception.
D.h. die Form wurde noch nicht erzeugt aber der Variableninhalt ist nicht nil und das sorgt für die Exception.
Re: Application.CreateForm(...
Bitte poste ein kleines Projekt, in dem man das nachvollziehen kann. Ich weiß, im 1.Post hängt ein Projekt dran, aber im Lauf der Diskussion kamen einige Vorschläge, und mir ist nicht klar, von welchem Status des Projekts du jetzt ausgehst.Niesi hat geschrieben: Mo 18. Nov 2024, 12:48 Was mit fehlt, ist der Grund für den SIGSEGV, wenn ich "MyInfoForm.Free;" aufrufe. Sollte Free nicht so sein, dass das Objekt "destroyed" wird, wenn es noch existiert, aber nichts passiert, wenn es bereits erledigt ist?
- Niesi
- Lazarusforum e. V.
- Beiträge: 587
- Registriert: So 26. Jun 2016, 19:44
- OS, Lazarus, FPC: Linux Mint Cinnamon, Laz 4.1 Fpc 3.2.3 und allerlei mit FpcUpDeLuxe
- Kontaktdaten:
Re: Application.CreateForm(...
Ich habe jetzt eine Änderung vorgenommen, da ich MyInfoForm nicht als MainForm haben möchte. Daher muss jetzt im Menü das Anzeigen des OS per Mausklick gestartet werden. Nach dem MyInfoForm.Free; gibt es einen Fehler. Und ich habe im Kopf, dass das mit Free nicht passieren sollte ...wp_xyz hat geschrieben: Mo 18. Nov 2024, 14:51Bitte poste ein kleines Projekt, in dem man das nachvollziehen kann. Ich weiß, im 1.Post hängt ein Projekt dran, aber im Lauf der Diskussion kamen einige Vorschläge, und mir ist nicht klar, von welchem Status des Projekts du jetzt ausgehst.Niesi hat geschrieben: Mo 18. Nov 2024, 12:48 Was mit fehlt, ist der Grund für den SIGSEGV, wenn ich "MyInfoForm.Free;" aufrufe. Sollte Free nicht so sein, dass das Objekt "destroyed" wird, wenn es noch existiert, aber nichts passiert, wenn es bereits erledigt ist?
Jedenfalls Danke an ALLE für die Mühe ...
Wissen ist das einzige Gut, das sich vermehrt, wenn es geteilt wird ...
Re: Application.CreateForm(...
Warum willst du MyInfoForm überhaupt zerstören? Es wurde automatisch von Application erzeugt, also kümmert sich auch Application ums Aufräumen.
Zur Schutzverletzung kommt es, weil Application MyInfoForm NACH MainForm erzeugt hat. Beim Aufräumen ist die Reihenfolge umgekehrt, also zuerst wird MyInfoForm zerstört, dann MainForm. Wenn aber MainForm MyInfoForm selbst nochmal zerstören will, gibt es dieses schon nicht mehr
Zur Schutzverletzung kommt es, weil Application MyInfoForm NACH MainForm erzeugt hat. Beim Aufräumen ist die Reihenfolge umgekehrt, also zuerst wird MyInfoForm zerstört, dann MainForm. Wenn aber MainForm MyInfoForm selbst nochmal zerstören will, gibt es dieses schon nicht mehr
- Niesi
- Lazarusforum e. V.
- Beiträge: 587
- Registriert: So 26. Jun 2016, 19:44
- OS, Lazarus, FPC: Linux Mint Cinnamon, Laz 4.1 Fpc 3.2.3 und allerlei mit FpcUpDeLuxe
- Kontaktdaten:
Re: Application.CreateForm(...
Ja, das habe ich mit diesem Thread gelernt - aber sollte Free dann nicht einfach ignoriert werden?wp_xyz hat geschrieben: Mo 18. Nov 2024, 15:55 Warum willst du MyInfoForm überhaupt zerstören? Es wurde automatisch von Application erzeugt, also kümmert sich auch Application ums Aufräumen.
Zur Schutzverletzung kommt es, weil Application MyInfoForm NACH MainForm erzeugt hat. Beim Aufräumen ist die Reihenfolge umgekehrt, also zuerst wird MyInfoForm zerstört, dann MainForm. Wenn aber MainForm MyInfoForm selbst nochmal zerstören will, gibt es dieses schon nicht mehr
Hab' ich das falsch aufgefasst?
Wissen ist das einzige Gut, das sich vermehrt, wenn es geteilt wird ...
Re: Application.CreateForm(...
Der Lazarus-Weg, besteht darin, den Objektinspektor des Hauptformulars zu verwenden und dort unter Events die Option OnCreate auszuwählen. Füllen Sie dann die Prozedur mainform.OnCreate aus, die erscheint. Verwenden Sie nicht die Konstruktor-/Destruktor-Konstruktion. Schauen Sie sich einige einfache Beispiele im Lazarus-Wiki an.
Ich habe Ihr Programm auf die Standard-OnCreate-Nutzung von Lazarus umgestellt. Läuft einwandfrei.
Ich habe Ihr Programm auf die Standard-OnCreate-Nutzung von Lazarus umgestellt. Läuft einwandfrei.
- Dateianhänge
-
14~OSDetection&UsesTest.zip
- (140.23 KiB) 98-mal heruntergeladen
Re: Application.CreateForm(...
Wieso denn? Wie soll dein MainForm überhaupt mitkriegen, dass MyInfoForm vorher schon zerstört worden ist? Das sind zwei unabhängige Objekte, die nichts voneinander wissen. Gut, MyInfoForm könnte sich beim Zerstören auf nil setzen, das du dann in MainForm abfragen könntest. Aber das ist keinesfalls garantiert.Niesi hat geschrieben: Mo 18. Nov 2024, 15:57 Ja, das habe ich mit diesem Thread gelernt - aber sollte Free dann nicht einfach ignoriert werden?
Folge einfach der Grundregel: Für das Zerstören eines Objects ist derjenige verantwortlich, der es erzeugt hat. Oder anders herum: Zerstöre nur das, was du selbst erzeugt hast
- Niesi
- Lazarusforum e. V.
- Beiträge: 587
- Registriert: So 26. Jun 2016, 19:44
- OS, Lazarus, FPC: Linux Mint Cinnamon, Laz 4.1 Fpc 3.2.3 und allerlei mit FpcUpDeLuxe
- Kontaktdaten:
Re: Application.CreateForm(...
Ok, habi was gelernt ...
Wissen ist das einzige Gut, das sich vermehrt, wenn es geteilt wird ...