Entwickler-Ecke
Windows API - Virtual ListView (OwnerData) -> Speicherleck bei SubItems
worm - Sa 16.08.03 02:29
Titel: Virtual ListView (OwnerData) -> Speicherleck bei SubItems
Hallo!
Ich habe eine ListView mit OwnerData = True. Das Problem ist, wenn ich im OnData-Event den SubItems Werte zuweise, werden diese Strings scheinbar nie mehr freigegeben. Scrollt der User in der Liste hin und her, wird laufend neuer Speicher reserviert.
Zum Nachvollziehen des folgenden Codes nur eine ListView aufs Formular packen und OwnerData auf true setzen (ViewStyle=vsReport ist nichtmal nötig). Und eben die Ereignisse verknüpfen.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| var s: String;
procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem); begin with Item do begin Caption := s; SubItems.Add(s); end; end;
procedure TForm1.FormCreate(Sender: TObject); begin ListView1.Items.Count := 2048; Randomize; s := IntToStr(Random(MAXINT)); end; |
Ich hoffe, irgendwer hat eine Lösung für das Problem; entweder geschickter adden (gerne auch per API) oder Stringlisten wieder freigeben.
Danke, worm
worm - Mi 27.08.03 22:52
@Mods: Bitte verschieben :arrow: API!
So, ich glaube, ich habe das Problem jetzt geortet... in der VCL wird bei der Behandlung der
LVN_GETDISPINFO Notification [
http://msdn.microsoft.com/library/en-us/shellcc/platform/commctls/listview/notifications/lvn_getdispinfo.asp] (Message CN_NOTIFY, in TCustomListView.CNNotify) folgender Code verwendet:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| with PLVDispInfo(NMHdr)^.item do begin if (mask and LVIF_TEXT) <> 0 then if iSubItem = 0 then StrPLCopy(pszText, Item.Caption, cchTextMax - 1) else with Item.SubItems do if iSubItem <= Count then StrPLCopy(pszText, Strings[iSubItem - 1], cchTextMax - 1) else pszText[0] := #0; ... |
Der String wird durch StrPLCopy also in den Puffer pszText kopiert.
Jetzt Fragen dazu:
- Ist für diesen Puffer von Windows bereits Speicher reserviert oder könnte ich auch pszText auf meine bereits existierenden Strings zeigen lassen (die ich sowieso im Speicher habe und auch dort behalte)?
- Falls ich das könnte, kann ich irgendwie eine eigene Klasse von TCustomListView ableiten und dabei nur die Behandlung der Notification LVN_GETDISPINFO ändern?
- Hat noch jemand eine andere Idee?
Thx für alle Antworten, die da kommen mögen!
Cya, worm
worm - Sa 20.09.03 00:43
Hab mich nochmal damit beschäftigt und hab's jetzt selbst gelöst. War gar nicht soo kompliziert. Heißen Dank an
Luckie's Win32API-Tutorials [
http://www.luckie-online.de/tutorials/win32apituts/] (hab die ListView-Demo als Basis zum Experimentieren genommen) :D
Also gelöst habe ich es jetzt, indem ich die WM_NOTIFY-Messages abfange und die LVN_GETDISPINFO für meine ListView selbst behandle. Dadurch kommt die VCL gar nicht erst dazu, Speicher zu verschwenden:
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: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39:
| ...
uses ..., CommCtrl;
type TForm1 = class(TForm) ListView1: TListView; private procedure WMNOTIFY(var M: TWMNotify); message WM_NOTIFY; end;
const entry_name = 'Testname'; entry_size = 1234;
...
procedure GETDISPINFO(item: PLVITEM); begin with item^ do if (mask and LVIF_TEXT) <> 0 then case iSubItem of 0: pszText := PChar(entry_name); 1: wvsprintf(pszText, '%u', PChar(@entry_size)); end; end;
procedure TForm1.WMNOTIFY(var M: TWMNotify); begin with M.NMHdr^ do if hwndFrom = ListView1.Handle then case code of LVN_GETDISPINFO: GETDISPINFO(@PLVDispInfo(M.NMHdr)^.item); else Inherited; end else Inherited; end; |
Falls das jemand mal selbst ausprobieren will,
hier der Source für ein kleines Testprogramm [
http://home.arcor.de/f0k/lv-ownerdata.zip]... per Define lässt sich das Abfangen der Notification ein- und ausschalten und unten wird der Speicherverbrauch angezeigt. Bei der VCL-Version kostet es sogar Speicher, mit der Maus über die Einträge zu fahren. :roll:
Cya, worm
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 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!