"Achim Kalwa" schrieb am 07.12.2019 um 11:43:20:
Danke an dich und Björn für deine Antworten.
>> [...] CustomDraw[...] Also habe
>> ich die alte Komponente rausgeschmissen und durch ein Delphi-TListView
>> ersetzt. Von der Funktionalität her hat das auch geklappt (wenn man mal von
>> diversen Kunstgriffen absieht, die nötig waren, um bei einem TListView mit
>> OwnerData = True und Checkboxes = True die Checkboxen tatsächlich sichtbar
>> zu machen).
> Deine Lösung hierzu würde mich interessieren! Aber das nur am Rande.
Ich habe durch Überschreiben des CNNotify-Handlers die Verarbeitung von
LVM_GETDISPINFO-Botschaften modifiziert. Im Code sieht das ungefähr so aus:
procedure TFSTListView.CNNotify (var Msg : TMessage);
begin
case PNMHdr (Msg.lParam)^.code of
LVN_GETDISPINFO : if not OwnerDraw then
with PNMLVDispInfo (Msg.lParam)^.item do
if Checkboxes and (iSubItem = 0) and
(mask and LVIF_IMAGE = LVIF_IMAGE) then begin
mask := mask or LVIF_STATE;
stateMask := LVIS_STATEIMAGEMASK;
//Erläuterung von GetChecked siehe unten
if GetChecked (iItem) then
state := INDEXTOSTATEIMAGEMASK (2)
else
state := INDEXTOSTATEIMAGEMASK (1)
end;
(Bearbeitung anderer Botschaften...)
end;
inherited
end;
Zur Erläuterung: Die Funktion GetChecked () ist eine Methode, die den
Checked-Status der Checkbox aus den Daten ermittelt, mit der das Listview
gefüttert wurde. Bei diesen Daten handelt es sich um Objekte, die in einer
TList gespeichert sind und die eine Eigenschaft enthalten, die den Status der
Checkboxen bestimmt. Der Rest ist Windows API.
> Wieviele Items enthält Dein ListView denn?
Verschieden. Von wenigen Dutzend bis mehreren Tausend. Die Performance ist
aber schon bei wenigen Items grottig.
Inzwischen habe ich aber die Bremse gefunden: es ist der OnData-Handler. Der
muss bei jedem Aufruf dem übergebenen Item die Subitems hinzufügen, und aus
unerfindlichen Gründen dauert das lange (obwohl TItem.Subitems eigentlich nur
eine Stringlist ist, bei der das Hinzufügen von Strings normalerweise recht
schnell geht). Abhilfe: ich habe das Listview jetzt auf OwnerDraw umgestellt.
Es kostete zwar etwas Mühe, den OnItemDraw-Handler so zu programmieren, dass
das Listview wieder wie vorher (also mit OwnerDraw = False) aussieht. Aber
jetzt klappt das und die Performance ist auch wieder so, wie sie sein sollte.
Die Routinen, mit denen die Texte der Items und Subitems aus den Daten
ausgelesen werden, sind übrigens dieselben wie die, die ich vorher zum
Befüllen von Item.Caption und den SubItems genutzt habe. Trotzdem geht jetzt
alles viel schneller. Diese Routinen waren also nicht schuld an der schlechten
Performance.
Der o. g. CNNotify-Handler ist jetzt allerdings unnötig, denn die Checkboxen
werden jetzt im OnItemDraw-Handler gezeichnet. Auch dafür nutze ich Windows
API-Routinen, z. B. ListView_GetImageList (<Listview-Handle>,LVSIL_STATE) und
ImageList_Draw ().
Gruß
Michael