Autor Beitrag
galagher
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Di 15.12.09 19:34 
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:

ausblenden 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);  //Liest Dateisymbole in aIcon ein
  Glyph := TBitmap.Create;  // muss immer wieder erzeugt werden, da sonst alle Items das selbe Symbol zeigen
  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?

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: Di 15.12.09 21:03 
Hallo,

eventuell ist das auch was für dich: www.delphi-forum.de/....php?p=334000#334000


Freigeben bevor das Item gelöscht wird, mit einem TypeCast, etwa so:

ausblenden Delphi-Quelltext
1:
2:
TBitmap(Items.Objects[x]).Free;
Items.Delete(x);

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Di 15.12.09 21:20 
user profile iconLannes hat folgendes geschrieben Zum zitierten Posting springen:
Freigeben bevor das Item gelöscht wird, mit einem TypeCast, etwa so:

ausblenden 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?
ausblenden 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
//...

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: 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 ...

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Mi 16.12.09 21:51 
So funktioniert es immerhin:
ausblenden 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;  //Wird beim 1. Aufruf wie erwartet nicht, sondern erst bei Ordnerwechsel ausgeführt
  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?

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: 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?

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Do 17.12.09 21:09 
user profile iconLannes hat folgendes geschrieben Zum zitierten Posting springen:
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!

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: 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!

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!