![]() |
Combobox mit AddObject - Speicher automatisch freigeben
Hallo zusammen,
wie wandele ich mir eine ComboxBox so ab, dass Sie automatisch beim Zerstören die Objekte freigibt, die ich mit AddObject angefügt habe? Wenn ich den Destructor überschreiben und auf die Items zugreifen will bekomme ich die Meldung, dass die Combobox kein übergeordnetest Objekt hat. Weiss jemand rat? |
Re: Combobox mit AddObject - Speicher automatisch freigeben
Zitat:
|
Re: Combobox mit AddObject - Speicher automatisch freigeben
Delphi-Quellcode:
destructor TCustomImageComboBox.Destroy;
var i : Integer; begin FOR i := 0 TO FFItems.Count - 1 DO BEGIN IF FItems.Objects[i] <> nil THEN FItems.Objects[i].Free; END; inherited; end; |
Re: Combobox mit AddObject - Speicher automatisch freigeben
Zitat:
Wie sieht deine Klasse TCustomImageBox denn aus? Wovon leitest du ab? Bei meinem Test habe ich mal direkt von TComboBox abgeleitet:
Delphi-Quellcode:
Wenn ich irgendwo im Programm ein Combo.Free habe, so funktioniert das einwandfrei. In meinem Beispiel verschwindet das Label1 von der Form. :-)
type
... TCombo = class(TComboBox) public destructor destroy; override; end; var Combo: TCombo; ... procedure TForm1.FormCreate(Sender: TObject); begin ... Combo := TCombo.Create(Form1); Combo.Name:='Combo'; Combo.Parent:=self; Combo.Left := 448; Combo.Top := 64; Combo.Width := 145; Combo.Height := 21; Combo.ItemHeight := 13; Combo.Clear; Combo.Items.AddObject('Label',self.Label1); //Testobject ist Label1 auf Form1 end; destructor TCombo.destroy; var i : integer; begin for i := 0 to Combo.Items.Count-1 do begin Combo.Items.Objects[0].free; end; inherited; end; |
Re: Combobox mit AddObject - Speicher automatisch freigeben
Ok, hab alles aus den Klassen mal in ein Beispielprog geschrieben
Form enthält nur 2 Buttons, die Combo wird angelegt Nach Klick auf den Hinzufügen button wird beim Prog Ende kein Speicher freigegeben.
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TNeueComboBox = class; TNeuesComboBoxItem = class protected FOwner: TNeueComboBox; FItemIndex: Integer; FListID : Integer; FIndex: Integer; FIndentLevel: Integer; FImageIndex: Integer; FOverlayIndex: Integer; FCaption: string; FTag: Integer; FData: Pointer; procedure SetIndentLevel( Value: Integer ); procedure SetImageIndex( Value: Integer ); procedure SetCaption( const Value: string ); procedure SetOverlayIndex( Value: Integer ); public constructor Create( AOwner: TNeueComboBox ); destructor Destroy; override; property Index: Integer read FIndex; property IndentLevel: Integer read FIndentLevel write SetIndentLevel; property ImageIndex: Integer read FImageIndex write SetImageIndex; property OverlayIndex: Integer read FOverlayIndex write SetOverlayIndex; property Caption: string read FCaption write SetCaption; property Data: Pointer read FData write FData; property Tag: Integer read FTag write FTag; property ListID: Integer read FListID write FListID; end; TNeueComboBox = class(TCustomComboBox) public destructor Destroy; override; function AddItem(Caption: string; ImageIndex: Integer; IndentLevel: Integer; ListID: Integer ): TNeuesComboBoxItem; end; type TForm1 = class(TForm) btn_Hinzu: TButton; btn_Delete: TButton; procedure FormCreate(Sender: TObject); procedure btn_HinzuClick(Sender: TObject); procedure btn_DeleteClick(Sender: TObject); private FComboBox : TNeueComboBox; { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} constructor TNeuesComboBoxItem.Create( AOwner: TNeueComboBox ); begin inherited Create; FOwner := aOwner; FOverlayIndex := -1; end; destructor TNeuesComboBoxItem.Destroy; begin inherited; end; procedure TNeuesComboBoxItem.SetIndentLevel( Value: Integer ); begin FIndentLevel := Value; FOwner.Invalidate; end; procedure TNeuesComboBoxItem.SetImageIndex( Value: Integer ); begin FImageIndex := Value; FOwner.Invalidate; end; procedure TNeuesComboBoxItem.SetCaption( const Value: string ); begin FCaption := Value; FOwner.Invalidate; end; procedure TNeuesComboBoxItem.SetOverlayIndex( Value: Integer ); begin FOverlayIndex := Value; FOwner.Invalidate; end; function TNeueComboBox.AddItem( Caption: string; ImageIndex: Integer; IndentLevel: Integer; ListID: Integer ): TNeuesComboBoxItem; const NOSTRING: string = ''; begin Result := TNeuesComboBoxItem.Create(Self); Result.FCaption := Caption; Result.FImageIndex := ImageIndex; Result.FIndentLevel := IndentLevel; Result.ListID := ListID; Result.FIndex := inherited Items.AddObject( Caption, Result ) end; destructor TNeueComboBox.Destroy; begin WHILE Items.Count > 0 DO Items.Delete(0); inherited; end; procedure TForm1.btn_DeleteClick(Sender: TObject); begin FComboBox.Items.Clear; end; procedure TForm1.btn_HinzuClick(Sender: TObject); begin FComboBox.AddItem('Name', 0, 0, 0); end; procedure TForm1.FormCreate(Sender: TObject); begin FComboBox := TNeueComboBox.Create(self); FComboBox.Parent := self; end; end. |
Re: Combobox mit AddObject - Speicher automatisch freigeben
Die Kiste verschluckt sich einfach. Ich habe keine Ahnung, warum. :(
Es passt aber der schöne Spruch dazu, dass alles, was man im Constructor created, man im Destructor wieder destroyen soll. Baue mal das folgende dazu, dann sollte es mit der Fehlermeldung vorbei sein:
Delphi-Quellcode:
procedure TForm1.FormDestroy(Sender: TObject);
begin FComboBox.Free; end; Dann noch was: Zitat:
Benutze Items.Objects[].Free, so wie du es schon in deinem zweiten Posting hier angedeutet hattest. |
Re: Combobox mit AddObject - Speicher automatisch freigeben
Ich hab mittlerweile festgestellt, dass wenn ich die Items auf TComponent basieren lasse (TNeuesComboBoxItem = class(TComponent), macht er er es.
|
Re: Combobox mit AddObject - Speicher automatisch freigeben
Zitat:
Das ist aber irgendwie von hinten durch die Brust ins Auge. Damit erzwingst/ermöglichst du möglicherweise - auf was für Kosten auch immer - dass deine Combobox ihre Einträge bzw. die Objekte in den Einträgen automatisch freigibt. Also so, wie eine Form für die Freigabe der visuellen Komponenten auf ihr verantwortlich ist. War das die ganze Zeit dein Ziel? Da finde ich aber die manuelle Freigabe sowohl der Listen-Objekte in TComboBox.Destroy als auch deiner ComboBox mittels ComboBox.Free in TForm.Destroy viel sauberer. |
Re: Combobox mit AddObject - Speicher automatisch freigeben
ne das war nicht mein ziel,
das prob ist aber, dass ich das free event nicht auslösen kann, weil die kombo ja von der ide erzeugt wird und nicht wie in meinem beispiel zur runtime. also kann ich den destroy nicht aufrufen, für jede kombo die ich auf die maske lege, oder? |
Re: Combobox mit AddObject - Speicher automatisch freigeben
Zitat:
Offen gestanden ergeben sich für mich von einem Posting von dir zum nächsten zuviele Abweichungen. Das mit der Ide (also Entwurfszeit) ist ja nun völlig neu. Zitat:
Allerdings möchte ich mich jetzt auch langsam ausklinken, weil ich heute sehr lange an dieser Sache herumgetestet habe und nun hören muss, dass alles nicht der wirklichen Umsetzung entsprach. Sorry. Nur soviel noch: Ich würde - wenn es tatsächlich eine Komponente zum Auf-die-Form-ziehen werden soll - tatsächlich auch gucken, dass sie automatisch freigegeben wird. Die Komponente! Die in der Liste enthaltenen Objekte könntest du dabei aber trotzdem manuell freigeben. Sie werden ja auch manuell zur Laufzeit created. Bei einer normalen ComboBox muss man das auch so tun. Letztlich hält die Liste ja nur Referenzen auf Objekte und oftmals wäre es im wahrsten Sinne des Wortes zerstörerisch, wenn bei der Löschung einer Auflistung von Gegenständen, die Gegenstände gleich selbst mit zerlegt würden. ;-) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:42 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-2025 by Thomas Breitkreuz