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/)
-   -   Delphi Komponeten zerstören (https://www.delphipraxis.net/9688-komponeten-zerstoeren.html)

LoL 1. Okt 2003 19:26


Komponeten zerstören
 
hi

ich erzeuge komponeten zur laufzeit. nun will ich diese zerstören. ich will dafür ne allgemein prozedur verwenden etwa so:
Delphi-Quellcode:
procedure Destroy_Component(Compo : TComponent);
begin
  if Compo <> nil then
    begin
      Compo.Destroy;
      Compo := nil;
      Compo.Free;
    end;
end;
das zerstören klappt auch so weit.
wenn ich aber diese komponenten die zerstört ist, wieder erstellen will frage ich
Delphi-Quellcode:
if not(assigned(Compo )) then <--Compo ist die zertörte komponete
....
erstellen der komponente
diese abfrage ist aber false!, d.h. die komponente existiert noch.

wenn ich aber die komponete ohne diese prozedur zerstöre also manuell(z.b. ein panel):
Delphi-Quellcode:
panel.destroy;
panel := nil;
panel.free;
und dann die abfrage mache ob die komponente noch existiert ist diese true! obwohl ich das selbe gemacht habe?

wer kann mir helfen

Dagon 1. Okt 2003 19:29

Re: Komponeten zerstören
 
Versuchs mal mit FreeAndNil:

Delphi-Quellcode:
procedure Destroy_Component(Compo : TComponent);
begin
  if Compo <> nil then
    FreeAndNil(Compo);  
end;

LoL 1. Okt 2003 19:33

Re: Komponeten zerstören
 
will ich nicht kannst du mir sagen woran es liegt

Dagon 1. Okt 2003 19:39

Re: Komponeten zerstören
 
1. Mit Assignde prüfst du ob der Zeiger (hier Compo) den Wert nil hat.

2. Folgendes steht in der OH:
Zitat:

Assigned gibt false zurück, wenn P den Wert nil hat, andernfalls true.

LoL 1. Okt 2003 19:47

Re: Komponeten zerstören
 
wenn ich die komponente nach obiger prozedur zertöre und frei gebe dann ist sie nil: also warum gibt dann assign true zurück?

Chewie 1. Okt 2003 19:54

Re: Komponeten zerstören
 
Ersetz mal
Delphi-Quellcode:
procedure Destroy_Component(Compo : TComponent);
begin
  if Compo <> nil then
    begin
      Compo.Destroy;
      Compo := nil;
      Compo.Free;
    end;
end;
durch
Delphi-Quellcode:
procedure DestroyComponent(Compo: TComponent);
begin
  if Compo <> nil then
  begin
    Compo.Free;
    Compo := nil;
  end;
end;

Dagon 1. Okt 2003 19:55

Re: Komponeten zerstören
 
Es gibt false zurück!

Du hast ja geschrieben if not(assigned(Compo)) = true ....
Das würde also beduten, diese Aussage ist wahr, wenn Assigned False zurückgibt.

Ergo: Compo ist Nil!

LoL 1. Okt 2003 20:13

Re: Komponeten zerstören
 
Die Funktion Assigned prüft, ob ein Zeiger oder eine Prozedurvariable den Wert NIL hat (nicht zugewiesen ist).

if Assigned(Component) then //Instanz erstellt

ich frage ja bevor ich die komponete erstelle ob sie nil ist. falls sie nämlich scho existiert bekomme ich ja ne exception!

Dagon 1. Okt 2003 20:15

Re: Komponeten zerstören
 
Das ist genau das was ich gemeint habe.

LoL 1. Okt 2003 20:28

Re: Komponeten zerstören
 
also passt die abfrage aber was ist der unterschied zwischen dem zerstören in der prozedur und der manuellen zerstörung?

ArrayOf.. 1. Okt 2003 20:46

Re: Komponeten zerstören
 
Du destroyst die Componente zwar, aber du NIL'st nur die temporäre Variable 'Compo' dieser Procedure 'Destroy_component'. Die TComboBox-Instanz die du beim Aufruf dieser Procedure in der Parameterliste mitgegeben hast wird zwar so auch freigegeben aber eben nicht geNILt, weil es zwei unterschiedliche Ptr-Variablen sind.

Der Ptr in deiner Procedure-Parameterliste übernimmt den Ptr-Wert auf die zu löschende CompoBox, wodurch deren Speicher dann freigegeben wird. Anschließend wird aber nur dein Ptr in der Procedure geNILt und eben nicht der 'draußen'.

Versuche mal in deinem Procedurekopf diese 'Compo'-Variable als 'var' zu declarieren:

procedure Destroy_Component(var Compo : TComponent);

LoL 1. Okt 2003 20:53

Re: Komponeten zerstören
 
ok so weit so gut aber wenn ich das so ändere und compilieren will dann erhalte ich folgende fehlermeldung:
Zitat:

Types of actual and formal var parameters must be identical
Delphi-Quellcode:
procedure Destroy_Component(var Compo : TComponent);
begin
  if Compo <> nil then
    begin
      Compo.Destroy;
      Compo := nil;
      Compo.Free;
    end;
end;

//beim panel zerstören:
Destroy_Component(beispielpanel);
zu deutsch

Bei einem Variablenparameter muß das eigentliche Argument genau denselben Typ wie der formale Parameter aufweisen.

was mache ich falsch

Christian Seehase 1. Okt 2003 20:59

Re: Komponeten zerstören
 
Moin Christoph,

nimm TObject und nicht TComponent.
TObject ist der Vorfahr für alle.

LoL 1. Okt 2003 21:05

Re: Komponeten zerstören
 
Zitat:

Zitat von Christian Seehase
nimm TObject und nicht TComponent.
TObject ist der Vorfahr für alle.

das gleiche....
mit TPanel gehts auch net

Christian Seehase 1. Okt 2003 21:09

Re: Komponeten zerstören
 
Moin Christoph,

probier's mal so:

Delphi-Quellcode:
procedure Destroy_Component(Compo : TObject);
begin
  if Compo <> nil then
    begin
      Compo.Free;
      Compo := nil;
    end;
end;

Dagon 1. Okt 2003 21:12

Re: Komponeten zerstören
 
Ist das nicht das selbe wie

Delphi-Quellcode:
procedure Destroy_Component(Compo : TObject);
begin
  if Compo <> nil then
    begin
      FreeAndNil(Compo);
    end;
end;
:?:

LoL 1. Okt 2003 21:16

Re: Komponeten zerstören
 
der akzeptiert ja scho nicht mal die übergabe parameter

ArrayOf.. 1. Okt 2003 21:19

Re: Komponeten zerstören
 
Ne, ich weiß nicht ob das überhaupt geht. Du musst ja nachher auch den entsprechend zu deinem Objekt korrekt passenden klassenrefferenzierten Destructor aufrufen und das wird in dieser Destroy-Routine wahrscheinlich nicht so einfach möglich sein, wenn überhaupt, imo.

LoL 1. Okt 2003 21:21

Re: Komponeten zerstören
 
also kann man nicht eine prozedur schreiben die jede art von komponeten zerstört und frei gibt?

Christian Seehase 1. Okt 2003 21:23

Re: Komponeten zerstören
 
Moin The Master,

Du hast doch die Pro Version.
Schau Dir mal in den Sourcen an wie FreeAndNil implementiert ist.

ArrayOf.. 1. Okt 2003 21:24

Re: Komponeten zerstören
 
@LoL

ich möchte hier nicht den Experten vorgreifen, aber ich glaube es eher weniger.

Dagon 1. Okt 2003 21:27

Re: Komponeten zerstören
 
@ Christian Seehase: Ich mich :oops:

Christian Seehase 1. Okt 2003 21:31

Re: Komponeten zerstören
 
Moin Christoph,

Zitat:

Zitat von LoL
also kann man nicht eine prozedur schreiben die jede art von komponeten zerstört und frei gibt?

Die gibt es schon. Die heisst FreeAndNil.

[EDIT]
Zitat:

Zitat von the_master
@ Christian Seehase: Ich mich :oops:

Warum das denn? Man kann ja nicht immer an alles denken.
[/EDIT]

LoL 1. Okt 2003 21:34

Re: Komponeten zerstören
 
freeandnil macht das:
Delphi-Quellcode:
procedure FreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  Temp.Free;
end;´
hab ich probiert geht aber irgendwie nicht. die abfrage gibt immer noch false zurück

ArrayOf.. 1. Okt 2003 21:50

Re: Komponeten zerstören
 
ich nehm an, FreeAndNil benötigt in seiner Parameterliste aber immer eine Instanz deren Typ ursprünglich ist und nicht eine deren Typ durch eine Übergabe via Parameterliste erst noch quasi 'falsch' ge-typcastet wurde.

Chewie 1. Okt 2003 21:53

Re: Komponeten zerstören
 
Also: Ich nehm an, Beispielpanel ist vom Typ TPanel.
Dann sollte folgender Aufruf funktionieren:
Delphi-Quellcode:
destroy_components(TComponent(Beispielpanel));

ArrayOf.. 1. Okt 2003 21:57

Re: Komponeten zerstören
 
nein eigentlich gerade nicht. Ich formuliere dann, dass das Teil vom Typ TComponent wäre, FreeAndNil muss aber den Destructor von TPanel aufrufen. Ich weiß nicht ob die Routine das dann trotzdem noch so ohne weiteres kann.

Chewie 1. Okt 2003 22:06

Re: Komponeten zerstören
 
No prob. Das ist ja das schöne von Klassen: Eine Objektvariable ist ja nur ein Zeiger auf das Objekt. Durch den Cast des Panels in TComponent kann man zwar nur noch auf die Eigenschaften und Methoden von TComponent zugreifen, der Inhalt bleibt aber der gleiche. Es wird weiterhin der Destruktur von TPanel aufgerufen.

ArrayOf.. 1. Okt 2003 22:29

Re: Komponeten zerstören
 
Bist du sicher, also dass nach einem falschen Typcasting per Übergabe via Parameterliste immer noch der korrekte Destructor aufgerufen wird? Wo doch die typisierte Instanz-Variable auch sonst immer den Typ des gepointeten quasi entscheident bestimmt. Du sagst ja selbst, dass man dann nur noch auf die Eigenschaften und Methoden von TComponent zugreifen kann. Der Destructor ist aber prinzipiell auch nur eine dieser Methoden. Also ich glaub's eher nicht so richtig... Aber ich muss auch zugeben, 1000% weiß ich es hier auch nicht *g*.


edit: Und meines Wissens sind solche Destructoren auch nicht so eine Abart von diesen virtuellen Methoden, die ja irgendwie so eine ähnliche Fähigkeit besitzen.

Chewie 1. Okt 2003 23:01

Re: Komponeten zerstören
 
Du castest ja nur den Pointer, nicht den Inhalt! Welche Methode aufgerufen wird, bestimmt der Typ zur Laufzeit, nicht der im Quelltext angegebene!

Probiers mal selber aus:
Delphi-Quellcode:
type
  TMyObject = class
  public
    destructor Destroy; override;
  end;

destructor TMyObject.Destroy;
begin
  ShowMessage('Ich werde ausgeführt');
end;

var
  Obj: TObject;
begin
  Obj := TMyObject.Create;
  Obj.Free;
end;

Christian Seehase 1. Okt 2003 23:06

Re: Komponeten zerstören
 
Moin Chewie,

nur um mal die, nicht vorhandene, Problematik mit dem Typecast vorzuführen:

Delphi-Quellcode:
type
  TMyPanel = class(TPanel)
  public
    destructor Destroy; override;
  end;

implementation

{$R *.DFM}

destructor TMyPanel.Destroy;
begin
  ShowMessage('und kaputt...');
  inherited;
end;

procedure TForm1.Button1Click(Sender: TObject);

var
  mp : TMyPanel;

begin
  mp := TMyPanel.Create(self);
  TComponent(mp).Free;
end;

ArrayOf.. 1. Okt 2003 23:29

Re: Komponeten zerstören
 
stimmt, das mit dem Typcasting ist tatsächlich kein Problem. Hätte ich ehrlich nicht gedacht... gut, gut.


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