Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Form zur Laufzeit neu erstellen (https://www.delphipraxis.net/111365-form-zur-laufzeit-neu-erstellen.html)

HolgerCW 2. Apr 2008 11:38


Form zur Laufzeit neu erstellen
 
Hallo zusammen,

ich erstelle am Anfang eine Anmeldemaske. Nachdem das Passwort richtig eingegeben wurde mache ich folgendes:

Delphi-Quellcode:
FormAnmeldung.Free;
Wenn ich diese Form dann zur Laufzeit des Programmes wieder neu erstellen möchte, wollte ich das so machen:

Delphi-Quellcode:
Application.CreateForm(TFormAnmeldung, FormAnmeldung);
FormAnmeldung.Show;
Da tritt aber eine Zugriffsverletzung auf.

Was mache ich falsch ?

Gruss

Holger

DeddyH 2. Apr 2008 11:39

Re: Form zur Laufzeit neu erstellen
 
Versuch es mal mit
Delphi-Quellcode:
FormAnmeldung := TFormAnmeldung.Create(Application);

Sharky 2. Apr 2008 11:41

Re: Form zur Laufzeit neu erstellen
 
Ich mach das immer so:

Delphi-Quellcode:
implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  myForm2 : TForm2;
begin
  myForm2 := TForm2.Create(self);
  try
    myForm2.ShowModal;
  finally
    myForm2.Free;
  end;
end;

mkinzler 2. Apr 2008 11:43

Re: Form zur Laufzeit neu erstellen
 
Dann könntest du die Form auch ohne Owner erzeugen

Sharky 2. Apr 2008 11:46

Re: Form zur Laufzeit neu erstellen
 
Zitat:

Zitat von mkinzler
Dann könntest du die Form auch ohne Owner erzeugen

Meinst Du mich?
Ja, ich weiss. Ist mehr so "die Macht der Gewohnheit".

mkinzler 2. Apr 2008 11:47

Re: Form zur Laufzeit neu erstellen
 
Zitat:

Meinst Du mich?
Ja meinte ich.
ist ja nicht falsch aber unnötig.

HolgerCW 2. Apr 2008 11:53

Re: Form zur Laufzeit neu erstellen
 
Vielen dank an euch.

Wenn ich nun

Delphi-Quellcode:
FormAnmeldung.Free;
gemacht habe, müsste ich doch mit

Delphi-Quellcode:
if FormAnmeldung <> nil then ...
abfragen können ob die Form da ist oder nicht ?

-> Weil bei mir sagt er Sie wäre da obwohl ich ja vorher Free gemacht habe ?

Gruss

Holger

DeddyH 2. Apr 2008 11:54

Re: Form zur Laufzeit neu erstellen
 
Nein, Du musst entweder FreeAndNil verwenden oder den Objektzeiger selbst entwerten.

HolgerCW 2. Apr 2008 11:56

Re: Form zur Laufzeit neu erstellen
 
So ???

Delphi-Quellcode:
FormAnmeldung <> FreeAndNil;

DeddyH 2. Apr 2008 11:58

Re: Form zur Laufzeit neu erstellen
 
Entweder
Delphi-Quellcode:
FormAnmeldung.Free;
FormAnmeldung := nil;
oder
Delphi-Quellcode:
FreeAndNil(FormAnmeldung);

mkinzler 2. Apr 2008 11:59

Re: Form zur Laufzeit neu erstellen
 
Nein satt
Delphi-Quellcode:
Kompo.free;
Delphi-Quellcode:
FreeAndNil ( kompo);
verwenden. dann kannst du mit

Delphi-Quellcode:
if assigned( kompo)
abfragen ob das Objekt noch existent ist.

Hansa 2. Apr 2008 12:00

Re: Form zur Laufzeit neu erstellen
 
Warum hat FormClose einen Parameter ?

Delphi-Quellcode:
procedure Tfrm.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  inherited;
  Action := caFree;
end;
So sieht das normalerweise aus. Alles andere ist überflüssig. Bei kleineren Programmen ohne OOP auch das inherited. FreeAndNil-Orgien besorgt Delphi automatisch. :zwinker:

mkinzler 2. Apr 2008 12:17

Re: Form zur Laufzeit neu erstellen
 
Das ist natürlich bei modalen Eingabeformularen sehr geschickt, nach schließen des Formualar sind die Eigaben gleich weg. :gruebel:

HolgerCW 2. Apr 2008 12:25

Re: Form zur Laufzeit neu erstellen
 
Nun folgt das nächste Problem:

Wenn ich nun die Form "gefreet und genilt" habe und während der Laufzeit wieder erstelle, kommt hier eine Zugriffsverletzung:

Delphi-Quellcode:
procedure TFormAnmeldung.BitBtnOKClick(Sender: TObject);
begin

 //Kein Passwort
 if FormAnmeldung.CB_Anwender.text = '' then ...
Warum ?

Muss ich die ComboBox u.s.w. auch noch erstellen. Die müssten doch mit erstellt werden da ich ja hiermit erstelle:

Delphi-Quellcode:
FormAnmeldung := TFormAnmeldung.Create(Application);

FormAnmeldung.ShowModal;

Hansa 2. Apr 2008 12:26

Re: Form zur Laufzeit neu erstellen
 
Ja und ? Wenn der User das so will ? Das caFree wird im FormClose tätig. Es ist nicht dafür zuständig, dass dieses ausgelöst wird ! Außerdem gibts auch FormCloseQuery um gezielt vorzugehen.

Edit : bezieht sich hierdrauf :

Zitat:

Zitat von mkinzler
Das ist natürlich bei modalen Eingabeformularen sehr geschickt, nach schließen des Formualar sind die Eigaben gleich weg. :gruebel:


DeddyH 2. Apr 2008 12:26

Re: Form zur Laufzeit neu erstellen
 
Delphi-Quellcode:
procedure TFormAnmeldung.BitBtnOKClick(Sender: TObject);
begin

//Kein Passwort
if {FormAnmeldung.}CB_Anwender.text = '' then ...

messie 2. Apr 2008 12:29

Re: Form zur Laufzeit neu erstellen
 
Ich hab auch mal Action := caFree ausprobiert, der Verweis ist aber noch da. Da muss man also := nil noch nachschieben.

Grüße, Messie

Hansa 2. Apr 2008 12:38

Re: Form zur Laufzeit neu erstellen
 
Welcher Verweis ist noch da ? :shock: Habe hier zig Forms. Alle werden zum Anzeigen per create erzeugt und ohne Firlefanz mithilfe von cafree beim Close entfernt. Bei Bedarf werden sie also immer wieder neu erzeugt und das wars. Das gab noch nirgendwo einen Fehler.

messie 2. Apr 2008 12:48

Re: Form zur Laufzeit neu erstellen
 
Zitat:

Zitat von Hansa
Welcher Verweis ist noch da ? :shock: Habe hier zig Forms. Alle werden zum Anzeigen per create erzeugt und ohne Firlefanz mithilfe von cafree beim Close entfernt. Bei Bedarf werden sie also immer wieder neu erzeugt und das wars. Das gab noch nirgendwo einen Fehler.

Zitat:

Zitat von mkinzler
Delphi-Quellcode:
if assigned(Form) then

Diese Prüfung geht dann nicht. Und die kann recht wichtig sein, wenn man mit nichtmodalen oder mdi-Fenstern arbeitet.

Grüße, Messie

HolgerCW 2. Apr 2008 13:15

Re: Form zur Laufzeit neu erstellen
 
Wenn ich die Form mit Form.Show anstatt Showmodal anzeige klappt es ... Warum ?

RavenIV 2. Apr 2008 13:16

Re: Form zur Laufzeit neu erstellen
 
Zitat:

Zitat von mkinzler
Das ist natürlich bei modalen Eingabeformularen sehr geschickt, nach schließen des Formualar sind die Eigaben gleich weg. :gruebel:

Worin liegt der Sinn, auf Elemente eines gelöschten Objekts zuzugreifen?
Wenn ich ein Fenster schliesse, dann brauche ich auch die Eingabefelder nicht mehr.
Beim Schliessen (z.B. OK-Button) soll das Fenster (Formular) selber dafür sorgen, dass die relevanten Eingaben dauerhaft gespeichert werden. Entweder in einer ini oder in Variablen einer Daten-Unit.

Peinhard 2. Apr 2008 20:54

Re: Form zur Laufzeit neu erstellen
 
Nun, manchem mag es zB gefallen, die Eingaben eines modalen Dialogs in der aufrufenden Routine auszuwerten:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  with TForm2.Create(nil) do
  try
    ShowModal;
    //Eingaben auswerten
  finally
    Free;
  end;
end;

Hansa 2. Apr 2008 20:58

Re: Form zur Laufzeit neu erstellen
 
Zitat:

Zitat von RavenIV
...Beim Schliessen (z.B. OK-Button) soll das Fenster (Formular) selber dafür sorgen, dass die relevanten Eingaben dauerhaft gespeichert werden.

... oder auch nicht. Aber ich weiß, was Du meinst. Dafür gibt es ja OnCloseQuery. Bei mir steht da 1. "abbrechen" => zurück zum Form. 2. "speichern" => Daten speichern (Post, Commit...), Form schließen. 3. "Wollen sie die Änderungen nicht speichern " => otfalls Rollback etc. Hinzu kommt dann natürlich noch "Wollen sie wirklich nicht ...." also das Übliche. 8) Der Vorteil, Forms zur Laufzeit erst zu erzeugen, besteht eigentlich nur darin, dass die Ereignis - Sequenzen auch richtig durchlaufen werden und man auch lesbaren Quelltext hat, wo man auch nach Jahren noch sicher ist, das kein Seiteneffekt so nach Art von OnClick in irgendeinem zur Laufzeit erzeugten Button irgendwo einem alles verhagelt. Bei 10 EUR für 1 GB RAM ist alles andere Blödsinn.

Chemiker 3. Apr 2008 20:03

Re: Form zur Laufzeit neu erstellen
 
Hallo,

@Peinhard: Es ist doch ohne weiteres möglich mit dem out – Parameter noch nachträglich eine Auswertung vorzunehmen.

Delphi-Quellcode:
class function TFormSPSDAPPassWort.PassWortFreigabe (out Rueckgabe : Boolean): Boolean;
begin
  with TFormSPSDAPPassWort.Create(nil) do
    try
      Result := ShowModal=mrok; // ModalResult auf mrOk
      if Result then
        Rueckgabe := TRUE           // Rückgabe-Wert
       else
        Rueckgabe := FALSE;
     finally
       free;                   // Speicherfreigabe
   end;
end;

procedure TFormSPSDAPPassWort.Edit1Change(Sender: TObject);
begin
  if Edit1.Text = 'P' then  // Das Paßwort muss noch geändert werden.
    BitBtn3.Enabled := TRUE; // Der Button wird freigegeben
end;
Im Hautprogramm wird dann der out – Parameter ausgewertet. Im meinem Beispiel wird das Programm nur beendet, wenn das richtige Passwort eingegeben worden ist.

Delphi-Quellcode:
procedure TSPSDAPHauptForm.Beenden1Click(Sender: TObject);
begin
  TFormSPSDAPPassWort.PassWortFreigabe (PRG_Ende);
  if Prg_Ende then
  begin
    close;
  end;
end;
Bis bald Chemiker


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:55 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