AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Combobox mit AddObject - Speicher automatisch freigeben
Thema durchsuchen
Ansicht
Themen-Optionen

Combobox mit AddObject - Speicher automatisch freigeben

Ein Thema von backdraft · begonnen am 20. Feb 2007 · letzter Beitrag vom 23. Feb 2007
Antwort Antwort
Seite 1 von 2  1 2      
backdraft

Registriert seit: 19. Apr 2005
Ort: Hückeswagen
333 Beiträge
 
Delphi 11 Alexandria
 
#1

Combobox mit AddObject - Speicher automatisch freigeben

  Alt 20. Feb 2007, 10:10
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?
Oliver
  Mit Zitat antworten Zitat
IngoD7

Registriert seit: 16. Feb 2004
464 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: Combobox mit AddObject - Speicher automatisch freigeben

  Alt 20. Feb 2007, 10:20
Zitat von backdraft:
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?
Wenn du den Code postest, mit dem du es versucht hast, dann vielleicht.
  Mit Zitat antworten Zitat
backdraft

Registriert seit: 19. Apr 2005
Ort: Hückeswagen
333 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: Combobox mit AddObject - Speicher automatisch freigeben

  Alt 20. Feb 2007, 10:24
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;
Oliver
  Mit Zitat antworten Zitat
IngoD7

Registriert seit: 16. Feb 2004
464 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: Combobox mit AddObject - Speicher automatisch freigeben

  Alt 20. Feb 2007, 11:07
Zitat von backdraft:
Delphi-Quellcode:
destructor TCustomImageComboBox.Destroy;
var i : Integer;
begin
 FOR i := 0 TO FFItems.Count - 1 DO BEGIN // <=== doppeltes F ??
  IF FItems.Objects[i] <> nil THEN FItems.Objects[i].Free;
 END;
 inherited;
end;
Das doppelte F ist keine Absicht, oder?

Wie sieht deine Klasse TCustomImageBox denn aus? Wovon leitest du ab?


Bei meinem Test habe ich mal direkt von TComboBox abgeleitet:

Delphi-Quellcode:
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;
Wenn ich irgendwo im Programm ein Combo.Free habe, so funktioniert das einwandfrei. In meinem Beispiel verschwindet das Label1 von der Form.
  Mit Zitat antworten Zitat
backdraft

Registriert seit: 19. Apr 2005
Ort: Hückeswagen
333 Beiträge
 
Delphi 11 Alexandria
 
#5

Re: Combobox mit AddObject - Speicher automatisch freigeben

  Alt 20. Feb 2007, 11:29
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.
Oliver
  Mit Zitat antworten Zitat
IngoD7

Registriert seit: 16. Feb 2004
464 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: Combobox mit AddObject - Speicher automatisch freigeben

  Alt 20. Feb 2007, 14:19
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:
Delphi-Quellcode:
destructor TNeueComboBox.Destroy;
begin
  WHILE Items.Count > 0 DO Items.Delete(0);
  inherited;
end;
Mit Delete gibst du keine Objekte frei, du löscht nur die Referenz aus der Liste.
Benutze Items.Objects[].Free, so wie du es schon in deinem zweiten Posting hier angedeutet hattest.
  Mit Zitat antworten Zitat
backdraft

Registriert seit: 19. Apr 2005
Ort: Hückeswagen
333 Beiträge
 
Delphi 11 Alexandria
 
#7

Re: Combobox mit AddObject - Speicher automatisch freigeben

  Alt 20. Feb 2007, 14:36
Ich hab mittlerweile festgestellt, dass wenn ich die Items auf TComponent basieren lasse (TNeuesComboBoxItem = class(TComponent), macht er er es.
Oliver
  Mit Zitat antworten Zitat
IngoD7

Registriert seit: 16. Feb 2004
464 Beiträge
 
Delphi 7 Enterprise
 
#8

Re: Combobox mit AddObject - Speicher automatisch freigeben

  Alt 20. Feb 2007, 15:00
Zitat von backdraft:
Ich hab mittlerweile festgestellt, dass wenn ich die Items auf TComponent basieren lasse (TNeuesComboBoxItem = class(TComponent), macht er er es.

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.
  Mit Zitat antworten Zitat
backdraft

Registriert seit: 19. Apr 2005
Ort: Hückeswagen
333 Beiträge
 
Delphi 11 Alexandria
 
#9

Re: Combobox mit AddObject - Speicher automatisch freigeben

  Alt 20. Feb 2007, 15:21
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?
Oliver
  Mit Zitat antworten Zitat
IngoD7

Registriert seit: 16. Feb 2004
464 Beiträge
 
Delphi 7 Enterprise
 
#10

Re: Combobox mit AddObject - Speicher automatisch freigeben

  Alt 20. Feb 2007, 21:28
Zitat von backdraft:
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.
Das könnte aber vielleicht noch hier und da einen Unterschied ausmachen. Aber das weiß ich wirklich nicht genau.

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 von backdraft:
also kann ich den destroy nicht aufrufen, für jede kombo die ich auf die maske lege, oder?
Destroy solltest du nicht aufrufen, aber Free oder FreeAndNil wäre möglich. Warum denn nicht?

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.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:14 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