Delphi-PRAXiS

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/)
-   -   Problem mit verschiedenen Forms (https://www.delphipraxis.net/196038-problem-mit-verschiedenen-forms.html)

DomPerle 17. Apr 2018 13:47

Problem mit verschiedenen Forms
 
Habe jetzt schon lange in den Themen gesucht, aber noch nicht das richtige gefunden.
Meine Anwendung besteht aus Form1, Form2, Form3.

In Form1 Button1Click startet Form2 und Button2Click startet Form3.
Form3 := TForm3.Create( Self );
Form3.Show;
äquivalent
Form4 := TForm3.Create( Self );
Form4.Show;
Form3 und Form4 sollen gleichzeitig sichtbar sein.
Wird in Form1 ein anderes Member ausgewählt, so möchte ich erreichen, daß Form3 und/oder Form4 falls geöffnet, geschlossen werden.
Bei Form3.Close bzw. Form4.Close erhalte ich 'AccessViolation'.
Ausserdem werden bei Button1Click bzw. Button2Click immer neue Fenster göffnet.
Beim Form3.ShowModal bzw. Form4.ShowModal läßt sich immer nur eines der beiden Fenster öffnen.

Ich hoffe ich habe mich für einen Anfänger klug genug ausgedrückt.
Für schnelle Hilfe bedanke ich mich jetzt schon.

günni0 17. Apr 2018 14:43

AW: Problem mit verschiedenen Forms
 
Ich bin ja kein großer Freund davon, Fenster selber zu erzeugen.
Die IDE ist eine relativ gute IDE, wo man vieles nicht mehr von Hand machen muss. Lasse deine Fensterinstanzen doch alle beim Programmstart automatisiert erzeugen, und vergiss das TFormX.Create().
Dann brauchst du nur noch .Show und .Close und es gibt keine Zugriffgsverletzungen mehr.

Zitat:

Beim Form3.ShowModal bzw. Form4.ShowModal läßt sich immer nur eines der beiden Fenster öffnen.
Das ist ja auch der Sinn eines modalen Fensters :P

rapante 17. Apr 2018 14:52

AW: Problem mit verschiedenen Forms
 
Hallo DomPerle,
zeig doch mal deinen bisherigen Quelltext, dann fällt es eventuell leichter das Problem ausfindig zu machen.

bernau 17. Apr 2018 15:25

AW: Problem mit verschiedenen Forms
 
Zitat:

Zitat von günni0 (Beitrag 1399553)
Ich bin ja kein großer Freund davon, Fenster selber zu erzeugen.
Die IDE ist eine relativ gute IDE, wo man vieles nicht mehr von Hand machen muss. Lasse deine Fensterinstanzen doch alle beim Programmstart automatisiert erzeugen, und vergiss das TFormX.Create().
Dann brauchst du nur noch .Show und .Close und es gibt keine Zugriffgsverletzungen mehr.

Zitat:

Beim Form3.ShowModal bzw. Form4.ShowModal läßt sich immer nur eines der beiden Fenster öffnen.
Das ist ja auch der Sinn eines modalen Fensters :P

Neee. Oder? Nicht dein Ernst.

Für mich ist das schlimmste, wenn alle Fenster beim Programmstart erzeugt werden. Ein Projekt von mir hat ca. verschiedene 300 Forms. Wie lange soll das denn starten?:shock:

Bei nicht modalen Fenstern ist es auch mal erlaubt mehrere Instanzen der Form zu öffnen. Dann kommst du ohnehin nicht um ein TForm.Create herum.

günni0 17. Apr 2018 15:39

AW: Problem mit verschiedenen Forms
 
Zitat:

Neee. Oder? Nicht dein Ernst.
Doch ist mein Ernst. Nicht jeder hat aber auch 300 Formulare.
ich beispielsweise habe 29 und die werden innerhalb 250 Millisekunden geladen. Bis die vom Nutzer eingestellte Sprache übernommen und allen Einstellungen geladen wurden, noch einmal 110 Millísekunden. Ist jetzt kein Weltuntergang in meinem Fall.

ich gelobe Besserung, versprochen, indem ich meinen schändlichen Code... verbessere :P

himitsu 17. Apr 2018 16:26

AW: Problem mit verschiedenen Forms
 
Auch Modale Forms kann man mehrmals erzeugen.

Nimm z.B. eine TForm1, da drauf ein Button und darin dann
Delphi-Quellcode:
F := TForm1.Create(Self);
F.ShowModal;
Aber gerade dann, wenn Forms mehrfach erzeugt werden, darf man die globalen Form-Variablen vom Delphi nicht mehr benutzen.

Und bei Freigabe der Forms werden diese globalen Variablen nicht automatisch auf NIL gesetzt. Ein Publisched-Field im Owner der neuen Form würde automatisch NIL, wenn es genau so heißt, wie die neue Form (aber in diesem Owner darf/kann es dann auch nur je eine einzige Instanz geben)

hoika 17. Apr 2018 16:54

AW: Problem mit verschiedenen Forms
 
Hallo,
das ja zwei Fragen.

Zitat:

Ausserdem werden bei Button1Click bzw. Button2Click immer neue Fenster göffnet.
Du erzeugst ja auch jedes Mal mit TFormx.Create ein neues Fenster.
Delphi-Quellcode:
Form3 := TForm3.Create( Self );
Form3.Show;
Delphi-Quellcode:
if Form3=nil then
begin
  Form3 := TForm3.Create( Self );
end;
Form3.Show;
Zitat:

Bei Form3.Close bzw. Form4.Close erhalte ich 'AccessViolation'.
Wo genau?

Nimm besser
FreeAndNil(Form3);


Die Frage wäre hier auch noch, wer schließt Form3 und Form 4, in meinem Fall hier ist es das Hauptformular (Form1).
Sollte Form3 sich selber schließen wollen, rufst du Close in Form3 auf (Form3.Close wäre das gleiche, muss aber nicht, macht man auch nicht).
Dann musst du dem Hauptform irgendwie beibringen, das die globale Variable Form3 auf nil gesetzt werden muss.

günni0 17. Apr 2018 17:08

AW: Problem mit verschiedenen Forms
 
Zitat:

Dann musst du dem Hauptform irgendwie beibringen, das die globale Variable Form3 auf nil gesetzt werden muss.
Ich habe irgendwo mal gelesen, dass sich für solche Fälle (Fenster öffnen, erstellen, schließen, bekannt-machen und so) jemand eine Art Wrapper-Unit geschrieben hat, die für all das zuständig ist und auch über alles bescheid weiß.
Also im Prinzip eine einfache Unit die alles macht, tut, weiß und super-schlau ist.

Vielleicht hilft sowas ja.

hoika 17. Apr 2018 17:09

AW: Problem mit verschiedenen Forms
 
Hallo,
das wäre eine gute Entkopplung von Hauptformular.

DP-Maintenance 17. Apr 2018 19:48

Dieses Thema wurde am "17. Apr 2018, 20:48 Uhr" von "Daniel" aus dem Forum "Fragen / Anregungen zur DP" in das Forum "GUI-Design mit VCL / FireMonkey / Common Controls" verschoben.

DomPerle 18. Apr 2018 08:12

AW: Problem mit verschiedenen Forms
 
Bin begeistert, erstes Problem gelöst durch
if Form3=nil then
begin
Form3 := TForm3.Create( Self );
end;
Form3.Show;

Nun aber zum 2. Problem, wenn ich mit D'Click ein neues Member in Form1 auswähle, sollen Form3 und/oder Form4 geclosed werden. Da tritt die Schutzverletzung auf.
Der Befehl den ich verwende Form3.Close; Form4.Close;

DomPerle 18. Apr 2018 08:18

AW: Problem mit verschiedenen Forms
 
Habe gerade noch was anderes probiert und nun habe ich keine AccessViolation mehr und der Ablauf verhält sich nun so, wie ich ihn mir gedacht habe.
if Form3<>nil then
Form3.Close;
Vielen Dank an alle

DomPerle 18. Apr 2018 09:04

AW: Problem mit verschiedenen Forms
 
Jetzt habe ich mich so gefreut, doch nun geschieht noch was unangenehmes.

Nun aber zum 2. Problem, wenn ich mit D'Click ein neues Member in Form1 auswähle, sollen Form3 und/oder Form4 geclosed werden
Das klappt ja alles wunderbar, doch offensichtlich ist nach dem Closen Form3 bzw. Form4 immer ungleich nil, denn es wird kein neues Fenster mehr erstellt und somit erfolgt auch keine neue Aufbereitung.
Versuche mit Form3.Free; oder Form3.Destroy; ergeben wieder die AccessViolation. Was nun?

günni0 18. Apr 2018 10:08

AW: Problem mit verschiedenen Forms
 
Zitat:

denn es wird kein neues Fenster mehr erstellt und somit erfolgt auch keine neue Aufbereitung.
Ist die Aufbereitung im OnCreate-Event? Wenn ja, muss das selbstverständlich woanders hin.

himitsu 18. Apr 2018 10:31

AW: Problem mit verschiedenen Forms
 
Zitat:

Delphi-Quellcode:
if Form3<>nil then
Form3.Close;

Wenn die Form nicht nur geschlossen, sondern auch freigegeben wird: Da die Variable nicht auf nil gesetzt wird, knallt es dann beim zweiten Mal.

Da die Form nur geschlossen wird und nicht freigegeben (Free oder caFree im OnClose): bleibt die Form im Speicher, quasi als Speicherleck?

HolgerX 18. Apr 2018 12:23

AW: Problem mit verschiedenen Forms
 
Hmm..

Baue deine Forms um!

Verschiebe alles, was Du aktuell zur Aufbereitung im OnCreate machst in eine eigene Function (z.B. ExecuteWork), welche die Arbeit macht.

in deinem Buttonclick kommt dann nur noch

Delphi-Quellcode:
if Form3=nil then
begin
  Form3 := TForm3.Create( Self );
end;
Form3.Show;
Form3.ExecuteWork;
Wenn die Form dann geschlossen (Close) wird, ohne Free, würde diese durch das show einfach nur wieder visible gemacht und das ExecuteWork würde die Datenaufbereitung durchführen.
Das Close setzt (wenn nicht caFree im OnClose gesetzt wird) die Form nur auf Visible := False.

Dem ExecuteWork könntest Du noch weitere Parameter mitgeben, so dass sich das Form3 vielleicht gar nicht am Form1 bedienen muss, sondern komplett autark arbeitet.

KodeZwerg 18. Apr 2018 12:35

AW: Problem mit verschiedenen Forms
 
ot
Zitat:

Zitat von günni0 (Beitrag 1399584)
ich beispielsweise habe 29 und die werden innerhalb 250 Millisekunden geladen. Bis die vom Nutzer eingestellte Sprache übernommen und allen Einstellungen geladen wurden, noch einmal 110 Millísekunden.

Wie kommst Du auf diese Werte? Ich habe mir mal Spassenshalber ein Projekt erstellt mit 28 zusätzlichen Forms.
Auf jeder Form ist nur ein Label was beim Programmstart umbenannt wird.
Das umbennen erfolgt in einer Procedure für alle Forms nachdem diese erstellt wurden.
In der MainForm (das gibt es 2 Labels) werden mir die MS fürs erstellen der Fenster und fürs umbennen angezeigt.
Mit 250ms + 110ms komme ich absolut nicht hin.
Nutzt Du einen Super-Rechner mit 10 Cores oder so?
/ot

himitsu 18. Apr 2018 12:49

AW: Problem mit verschiedenen Forms
 
Ich aber hier eine Form, die braucht über 5 Sekunden, im FormDesigner noch mehr, und dann anschließend noch das Laden der Daten (DBGrids)

KodeZwerg 18. Apr 2018 12:56

AW: Problem mit verschiedenen Forms
 
@himitsu: Ja eben, 250+110 ist ja immer noch unter 1000ms (=1 Sekunde)
2500ms plus 1100ms wäre realistischer.

DomPerle 18. Apr 2018 17:17

AW: Problem mit verschiedenen Forms
 
Das Thema wurde verschoben und ich kann die Antworten auf meine Fragen nicht mehr findn, was nun?

himitsu 19. Apr 2018 09:38

AW: Problem mit verschiedenen Forms
 
Es wurde nur verschoben und nichts wurde abgesplittet oder gelöscht,
also nichts ist weg und alles nun hier.

In "Fragen / Anregungen zur DP" geht es um das Forum selbst.

DomPerle 19. Apr 2018 13:18

AW: Problem mit verschiedenen Forms
 
So, habe mein Problem wiedergefunden.
Ich habe jetzt das Problem so gelöst:

procedure TForm1.DeckelClick(Sender: TObject);
begin
If Form4 <> Nil Then
Form4.Destroy;

Form4 := TForm4.Create( Self );
Form4.Show;
end;

Der Versuch Form3 und/oder Form4 beim CreateForm1 zu schließen bringt einen AccessViolation. Warum, ist mir noch nicht ganz klar.
So wird auf jeden Fall beim DeckelClick die unit4 immer neu gestartet und die Form4 ist auch immer nur ein mal vorhande.
Danke für alles

hoika 19. Apr 2018 14:50

AW: Problem mit verschiedenen Forms
 
Hallo,
wenn du die Variable nicht auf Nil setzt, ist Sie natürlich nicht Nil.

Delphi-Quellcode:
If Form4 <> Nil Then
begin
  Form4.Destroy;

  Form4:= Nil;     <<-- Warum nicht einfach so?
end;

himitsu 19. Apr 2018 16:17

AW: Problem mit verschiedenen Forms
 
Abgesehn davon, dass man Delphi-Referenz durchsuchenTObject.Destroy im Normalfall nicht direkt aufrufen soll,

warum nicht Delphi-Referenz durchsuchenFreeAndNil?
Denn wenn es bei der Freigabe (im Destructor) knallt, dann gibt Delphi den Speicher dennoch frei, aber die Variable ist nicht nil.

DomPerle 20. Apr 2018 10:52

AW: Problem mit verschiedenen Forms
 
Danke für den Tipp, ich habe ihn befolgt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:31 Uhr.

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