Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TCheckListbox Auto-Destroy Objects (https://www.delphipraxis.net/136016-tchecklistbox-auto-destroy-objects.html)

Sereby 22. Jun 2009 09:48


TCheckListbox Auto-Destroy Objects
 
Hiho,

Verwende: Delphi 2009

ich habe bei meiner TCheckListBox per AddItem auch ein RecordObject hinzugefügt.
Dieses enthält 2 String Variablen!

Und nun versuche ich, leider vergeblich bisher, diese Objekte bei destroy freizugeben mit folgendem Code

Code:
  TCheckListBox = class(CheckLst.TCheckListBox)
  public
    destructor Destroy; override;
  end;

destructor TCheckListBox.Destroy;
var
  I: Integer;
  O: TObject;
begin
  for I := 0 to Items.Count - 1 do
  begin
    O := Items.Objects[I];
    if Assigned(O) then FreeAndNil(O);
  end;

  inherited Destroy;
end;
das problem an dem Code ist, dass er bei Items.Count schon eine Exception wirft die folgendes besagt:
"Element ... hat kein übergeordnetes Fenster"

so.. nun bitte ich euch mir zu helfen und zu sagen, wie ich es erreiche dass er automatisch bei Destroy die hinzugefügten Objekte aus dem Speicher entfernt?!

MfG Sereby

shmia 22. Jun 2009 11:04

Re: TCheckListbox Auto-Destroy Objects
 
1. )
Wenn du den Speicherplatz für den Record mit new angelegt hast, dann musst du ihn auch per dispose freigeben.
FreAndNil ist nur bei Objekten erlaubt.
2.)
Ich würde nicht TCheckListBox ableiten sondern das Freigeben im Event OnDestroy des Formulars ausführen:
Delphi-Quellcode:
procedure DisposeTStrings(sl: TStrings);
var
   i: Integer;
   p :Pointer;
begin
   for i := sl.Count-1 downto 0 do
   begin
      p := Pointer(sl.Objects[i]);
      if Assigned(p) then
      begin
         Dispose p;
         sl.Objects[i] := nil; // kann man sich auch schenken, soll doppelte Freigabe verhindern
      end;
   end;
end;

Sereby 22. Jun 2009 11:19

Re: TCheckListbox Auto-Destroy Objects
 
wenn ich das aber bei ondestroy mache, dann muss ich der procedure von jeder checkedlistbox die eigenschaft items übergeben.
aber genau das will ich automatisiert haben, sodass ich das nicht bei jeder checklistbox machen muss.

Muetze1 22. Jun 2009 13:21

Re: TCheckListbox Auto-Destroy Objects
 
1. ist es immer der selbe Record auf den gezeigt wird?
2. Beachtest du die Laufrichtung der Schleife? Shmia hat diese leise bei sich richtig herum gemacht?
3. Beachtest du, dass der Pointer Typ deinem Datentyp-Zeiger entsprechen muss für das Dispose?

Sereby 22. Jun 2009 13:29

Re: TCheckListbox Auto-Destroy Objects
 
1. ja es ist immer das selbe record
2. wär mir spätestens beim testen aufgefallen ^^
3. hmm.. wieso musser das denn?

shmia 23. Jun 2009 09:06

Re: TCheckListbox Auto-Destroy Objects
 
Zitat:

Zitat von Sereby
wenn ich das aber bei ondestroy mache, dann muss ich der procedure von jeder checkedlistbox die eigenschaft items übergeben.
aber genau das will ich automatisiert haben, sodass ich das nicht bei jeder checklistbox machen muss.

Ja schon, aber schau mal du hast jetzt das Reservieren von Speicher und das Freigeben an zwei unterschiedlichen Stellen.
Es geht die Checklistbox doch gar nix an, was in Items.Objects[] gespeichert ist.
Wenn du 4 Checklistboxen auf diese Weise benützt, dann steht halt im OnDestroy ungefähr das:
Delphi-Quellcode:
procedure TForm1.FormDestroy(Sender:TObject);
begin
  DisposeTStrings(Checklistbox1.Items);
  DisposeTStrings(Checklistbox2.Items);
  DisposeTStrings(Checklistbox3.Items);
  DisposeTStrings(Checklistbox4.Items);
  ...
end;
Das ist eine saubere und klare Sache. Vielleicht willst du auch mal statt Records richtige Objekte in Items.Objects[] ablegt - dann kommst du mit destructor TCheckListBox.Destroy aber ins Schleudern.

Blup 23. Jun 2009 09:36

Re: TCheckListbox Auto-Destroy Objects
 
Soll sich die Checklistbox doch selbst um die Freigabe kümmern, dafür sind Komponenten da.
Delphi-Quellcode:
TZusatzDaten = class(TComponent)
  constructor Create(AOwner: TComponent; AS1, AS2: string); reintroduce;
private
  FS1: string;
  FS2: string;
public
  property S1: string read FS1 write FS1;
  property S2: string read FS2 write FS2;
end;

constructor TZusatzDaten.Create(AOwner: TComponent; AS1, AS2: string);
begin
  inherited Create(AOwner);
  FS1 := AS1;
  FS2 := AS2;
end;

ChecklistBox.AddItem('ItemA', TZusatzDaten.Create(CheckListBox, 'Text1', 'Text2'));


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