Bildchen wollen Sie auch noch ...?


Na gut. Was wäre so eine List-View auch ohne die typischen Symbole? In diesem Kapitel wollen wir uns zuerst anschauen, wie wir eigene Grafiken verwenden können. Dazu benötigen wir eine so genannte ImageList. Diese wird mit Symbolen gefüllt und der List-View zugewiesen.

Sollte es notwendig sein, müssen wir je eine ImageList für die großen und eine für die kleinen Symbole erstellen. Wir schauen uns das anhand der kleinen Symbole einmal an: Mit ImageList_Create erzeugen wir die Image-Liste. Als Rückgabewert erhalten wir ein Handle, das wir nachher noch für die Zuweisung an das List-View-Control brauchen:

hImgSm  := ImageList_Create(16,16,ILC_COLOR,0,1);


Als nächstes füllen wir die Liste mit einem Symbol aus der Ressourcendatei:

ImageList_AddIcon(hImgSm,LoadIcon(hInstance,MAKEINTRESOURCE(1)));


Auf die gleiche Weise ließen sich natürlich noch weitere Symbole an die ImageList anhängen. Damit die List-View die Symbole aber auch nutzen kann, weisen wir die Liste mit der Nachricht "LVM_SETIMAGELIST" zu:

SendMessage(hLV,LVM_SETIMAGELIST,LVSIL_SMALL,hImgSm);

Der zweite Parameter ist das Handle unserer ImageList, und der erste Parameter beschreibt den Typ der Liste:

Wert Bedeutung
LVSIL_NORMAL Imagelist mit großen Symbolen
LVSIL_SMALL Imagelist mit kleinen Symbolen
LVSIL_STATE Imagelist mit Statussymbolen


Alternative

Diese Nachricht wird von der Funktion "ListView_SetImageList" gekapselt, die Sie ebenfalls verwenden können. Allerdings geben Sie das Handle der ImageList und den Typ in umgekehrter Reihenfolge an, z.B.:

ListView_SetImageList(hLV,hImgSm,LVSIL_SMALL);

Bei der Zuweisung der Liste für die großen Symbole ist ebenso vorzugehen. Bleibt nur noch die Frage: Wie kann ein Item in der List-View ein solches Symbol verwenden? Dazu möchte ich Sie an das letzte Kapitel erinnern, in dem es um das Füllen der List-View ging. Wenn Sie den ersten Eintrag (bezogen auf die Spalte mit dem Index Null) in die List-View eintragen wollen, ergänzen Sie bitte die Maske wie folgt:

lvi.mask     := LVIF_TEXT or LVIF_IMAGE;

Damit steht Ihnen die Membervariable iImage zur Verfügung, der Sie den Index des gewünschten Symbols übergeben. Wenn wir davon ausgehen, dass wir nur ein Symbol in der ImageList haben, lautet der Aufruf also ganz einfach nur:

lvi.iImage   := 0;

Dann wird der Eintrag wie im letzten Kapitel beschrieben mit "LVM_INSERTITEM" (bzw. "ListView_InsertItem") eingetragen und sollte das Symbol dann auch anzeigen.
Ich habe übrigens festgestellt, dass durch die Zuweisung einer ImageList automatisch das erste Symbol für alle Items benutzt wird, wenn Sie keine speziellen Angaben treffen. Wenn Ihre Einträge also alle das selbe (erste) Symbol der Liste anzeigen sollen, dann können Sie auf das Flag LVIF_IMAGE verzichten und die iImage-Membervariable ignorieren.

Bilder für Sub-Items

In der Detailansicht (LVS_REPORT-Stil) können Sie auch die Einträge in anderen Spalten mit Grafiken versehen. Dazu verwenden Sie, wie eben gezeigt, eine entsprechende Maske und übergeben den Indexwert des gewünschten Bildes, beispielsweise

lvi.mask     := LVIF_TEXT or LVIF_IMAGE;
lvi.iImage   := 1;

usw. Zusätzlich müssen Sie aber ein erweitertes Stilattribut setzen, sonst werden die Grafiken nicht angezeigt:

SendMessage(hLV,LVM_SETEXTENDEDLISTVIEWSTYLE,0,
  { ... } or LVS_EX_SUBITEMIMAGES);

Soll die List-View in dem Fall vor dem ersten Eintrag kein Symbol anzeigen, dann erinnern Sie sich bitte daran, was ich eben schrieb: Durch die Zuweisung einer ImageList wird automatisch das erste Symbol benutzt, selbst wenn Sie das nicht explizit angeben.
Sie können dieses Verhalten nur durch einen "Trick" umgehen, indem Sie nämlich das Flag LVIF_IMAGE für den ersten Eintrag benutzen, der iImage-Variablen aber den Wert -1 (I_IMAGENONE) übergeben:

lvi.mask     := LVIF_TEXT or LVIF_IMAGE;
lvi.iImage   := I_IMAGENONE;

Das hat allerdings den recht unschön wirkenden Nachteil, dass trotzdem links neben dem Eintrag der Platz für die Grafik frei ist. Das hängt aber mit der Zuweisung der Imageliste zusammen. Nur wenn Sie keine Liste verwenden, sind die Einträge direkt am linken Rand.
Abgesehen davon sieht das bestenfalls im Report-Modus gut aus. Sobald Sie eine andere Ansicht verwenden, wird standardmäßig wieder der erste Eintrag mit seinem (dann evtl. nicht vorhandenen) Symbol benutzt, was u.U. zu merkwürdigen Ergebnissen führt.


Die ImageList freigeben

Mit der Funktion ImageList_Destroy wird der Speicher für die Liste wieder freigegeben. Das also bitte nicht bei "WM_DESTROY" vergessen:

case uMsg of
  WM_DESTROY:
    ImageList_Destroy(hImgSm);
end;