Entwickler-Ecke
Multimedia / Grafik - AddObject und in Schleife erzeugtes Bitmap
galagher - Di 15.12.09 19:34
Titel: AddObject und in Schleife erzeugtes Bitmap
Hallo!
Ich versuche, die Komponente TFileListBox zu modifizieren. Es sollen beim Einlesen der Dateinamen auch deren Symbole ausgelesen und per Items.AddObject den Items zugewiesen werden. Das klappt auch, aber nur so:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| procedure TFileListBox.ReadFileNames; var I: Integer; Glyph: TBitmap; aIcon: TIcon; begin aIcon := TIcon.Create; if FindFirst(MaskPtr, AttrWord, FileInfo) = 0 then begin repeat GetIconFromFile(FileInfo.Name, aIcon, True); Glyph := TBitmap.Create; IconToBitmap(aIcon, Glyph); Glyph.Height := 16; Glyph.Width := 16; I := Items.AddObject(FileInfo.Name, Glyph); finally aIcon.Free; end; |
Meine Frage nun: Wie und wo wird das TBitmap Glyph wieder freigegeben? Es wird je immer wieder neu erzeugt, jedesmal, wenn man den Ordner wechselt, läuft die Prozedur ReadFileNames und es werden immer mehr von diesen Glyph-TBitmaps erzeugt.
Das funktioniert, aber ist das auch ok? Was ist mit dem Speicher?
Delphi-Hilfe:
Zitat: |
Das TStringList-Objekt wird nicht zu Eigentümer der hinzugefügten Objekte. Diese Objekte exisitieren weiter, auch wenn die TStringList-Instanz freigegeben wird. Diese Objekte müssen explizit von der Anwendung freigegeben werden. |
Wie müssen sie freigegeben werden?
galagher - Di 15.12.09 21:20
Lannes hat folgendes geschrieben : |
Freigeben bevor das Item gelöscht wird, mit einem TypeCast, etwa so:
Delphi-Quelltext 1: 2:
| TBitmap(Items.Objects[x]).Free; Items.Delete(x); | |
Ich weiss bloss nicht, wo das oder die Items gelöscht werden! Etwa direkt am Anfang der Prozedur ReadFileNames?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| procedure TFileListBox.ReadFileNames; var I: Integer; Glyph: TBitmap; aIcon: TIcon; begin aIcon := TIcon.Create; for i := Items.Count-1 downto 0 do begin TBitmap(Items.Objects[i]).Free; Items.Delete(i); end; if FindFirst(MaskPtr, AttrWord, FileInfo) = 0 then begin repeat |
Lannes - Mi 16.12.09 00:13
Hallo,
im Code der Unit FileCtrl in der Prozedur TFileListBox.ReadFileNames wird ziemlich am Anfang Clear aufgerufen, und zwar das von TCustomListBox, darin FItems.Clear. Das wiederum TListBoxStrings.Clear aufruft, darin wird ListBox.ResetContent aufgerufen.
In der Procedur erfolgte ein Message mit LB_RESETCONTENT das TWinControl auf den Plan ruft mit Gethandle >> HandleNeeded.
Dann gehts weiter mit Assembler in der StdWndProc, Call [ECX].Pointer verzweigt in TWinControl.MainWndProc und dann wird Window.Proc aufgerufen und jetzt habe ich keine Lust mehr weiter das zu verfolgen ...
galagher - Mi 16.12.09 21:51
So funktioniert es immerhin:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| for i := Items.Count-1 downto 0 do begin if Assigned(TBitmap(Items.Objects[i])) then TBitmap(Items.Objects[i]).Free; Items.Delete(i); end; |
TBitmap(Items.Objects[i]).Free; wird 7x ausgeführt, wenn in einem Ordner 6 Dateien sind. Ok, 7x bei 6 Dateien ist mir jetzt nicht ganz klar, aber es funktioniert prinzipiell. Meine Frage konkret: Gibt das den Speicher der TBitmaps frei, der zuvor belegt wurde?
Lannes - Do 17.12.09 19:59
Hallo,
ja, sollte freigegeben sein.
Das würde mich auch wundern, 6 Dateien, aber 7 Freigaben. Items.Count kann nicht unter 7 liegen, sonst würde es eine Zugriffsverletzung geben. Wie hoch ist den die Anzahl der TBitmap.Create-Aufrufe in dem zuvor ausgeführten ReadFileNames?
galagher - Do 17.12.09 21:09
Lannes hat folgendes geschrieben : |
Wie hoch ist den die Anzahl der TBitmap.Create-Aufrufe in dem zuvor ausgeführten ReadFileNames? |
Es sind bei 6 Dateien genau 6 Read's und 6 Free's. Wie ich dann auf 7 kam? Ich habe mir einen Haltepunkt gesetzt und habe 1 zuviel gezählt. Mit Integers als Zähler klappte es jetzt!
Vielen Dank, also werde ich den Code so lassen!
galagher - Sa 19.12.09 10:35
Hallo!
Bin jetzt soweit fertig mit der filectrl.pas und es funktioniert alles. Ist diese Datei in einem Package, wie kann ich das nun kompilieren, sodass die neuen Eigenschaften auch schon zur Entwurfszeit angezeigt werden?
//Edit: Hat sich erledigt - habe es zu einer eigene Komponente umgebaut!
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!