Dzisiaj omówimy sobie jedną z ważniejszych kontrolek WinApi, jaką jest kontrolka ListView. Służy ona do wyświetlania informacji z możliwością przyporządkowania im ikon. Żeby móc używać niektórych opcji tej kontrolki, musimy posiadać bibliotekę ComCtl32.dll przynajmniej w wersji 6 (WinXP i następne). Wszystkie niżej wymienione funkcje znajdują się w pliku nagłówkowym commctrl.h. Najpierw najbardziej podstawowa rzecz, czyli utworzenie kontrolki: 

Żeby zapewnić załadowanie odpowiedniej biblioteki do obsługi tej kontrolki, musimy na samym początku wywołać funkcję InitCommonControls.
Kontrolka ListView posiada 4 różne typy widoków wyświetlanych informacji i odpowiadające im flagi:
small icon view – LVS_SMALLICON, przy każdej pozycji, po lewej, jest wyświetlana mała ikona
icon view – LVS_ICON, przy każdej pozycji, wyświetlana jest ikona normalnych rozmiarów
list view – LVS_LIST, wyświetlana jest lista informacji, ikona jest po lewej
reported view – LVS_REPORT, widok kolumnowy, każda informacja jest umieszczona w oddzielnej linii, informacje w pierwszej kolumnie mogą posiadać ikonę, która wyświetlana jest po lewej, każda kolumna posiada nagłówek, ale można to zmienić, uwzględniając styl LVS_NOCOLUMNHEADER przy tworzeniu okna.

Jeżeli chcemy stworzyć kontrolkę z widokiem np. reported view, to musimy dołączyć odpowiednią flagę:

Możemy również używać rozszerzonych stylów, takich jak:
LVS_EX_CHECKBOXES – przy każdej informacji zostaje umieszczone pole checkbox
LVS_EX_FULLROWSELECT – cały rząd zostaje podświetlony przy zaznaczaniu pola
LVS_EX_FLATSB – zmienia scrollbary w kontrolce na płaskie
Żeby ustawić rozszerzony style kontrolki, używamy funkcji ListView_SetExtendedListViewStyle(uchwyt,styl):

My weźmiemy na warsztat widok LVS_REPORT, ponieważ jest najbardziej przydatny. A więc, przydało by się dodać parę kolumn. Służy do tego funkcja ListView_InsertColumn:

Teraz wystarczy tylko wywołać tą funkcję i mamy już gotowe kolumny:

Kolumny mamy, więc dodamy teraz parę pozycji. Jak zwykle jest do tego gotowa funkcja ListView_InsertItem. Jako jeden z parametrów podajemy strukturę LVITEM. Przyjrzyjmy się jej trochę bliżej:

Ta struktura służy również do pobierania informacji o danym polu, dlatego każde pole w zależności od kontekstu użycia musi być wypełnione (kiedy dodajemy pole) lub zostanie zwrócone (kiedy pobieramy informacje). A teraz po kolei parametry:
mask – flagi decydujące o tym, które pole muszą być wypełnione, lub które pola funkcja zwróci, może przyjmować, jedną lub więcej wartości:
LVIF_COLUMNS – pole cColums musi być wypełnione lub zostanie zwrócone
LVIF_GROUPID – pole iGroupId musi być wypełnione lub zostanie zwrócone
LVIF_IMAGE – pole iImage musi być wypełnione lub zostanie zwrócone
LVIF_INDENT – pole iIndent musi być wypełnione lub zostanie zwrócone
LVIF_PARAM – pole lParam musi być wypełnione lub zostanie zwrócone
LVIF_STATE – pole state musi być wypełnione lub zostanie zwrócone
LVIF_TEXT – pole pszText musi być wypełnione lub zostanie zwrócone
iItem – numer pola na którym operujemy
iSubItem – numer subitema na którym operujemy, jeżeli ustawimy wartość 0, to pole odnosi się do pozycji (informacji w pierwszej kolumnie)
state – wskazuje na stan pola
stateMask – informuje, o tym, które bity pola state mają być brane pod uwagę przy ustawianiu stanu pola
pszText – bufor z tekstem pola
cchTextMax rozmiar bufora
iImage – numer rysunku przypisanego do danego pola
lParam – wartość specyficzna dla każdego pola, używana przy sortowaniu pól
iIndent – pole to określa na ile szerokości obrazka przypisanego do danego pola wcięte będzie pole, standardowo 1

Dodajmy więc kilka pól do kontrolki. Stworzymy jedną funkcję, która będzie dodawała nowe pozycje, a potem wywołamy ją 5 razy:

Poznamy teraz możliwości jakie stwarza dla nas WinApi w zakresie modyfikowania wyglądu kontrolki ListView. Aby zmienić kolor tekstu użyjemy funkcji SendMessage, podając jako komunikat LVM_SETTEXTCOLOR:

Do zmiany koloru tła tekstu i tła kontrolki służą odpowiednio komunikaty LVM_SETTEXTBKCOLOR i LVM_SETBKCOLOR:

Jeżeli chcemy, aby kolor był całkowicie przeźroczysty, podstawiamy pod kolor wartość CLR_NONE. Przydatną rzeczą może również okazać się możliwość podstawienia obrazka jako tło kontrolki:

Powyższy kod ustawia jako tło kontrolki plik d:\rys.bmp i rysuje go kafelkowo. Jeżeli chcemy, aby obrazek został tylko raz narysowany zamiast flagi LVBKIF_STYLE_TILE podstawiamy flagę LVBKIF_STYLE_NORMAL. Ponieważ kontrolka ListView używa techniki OLE przy obsłudze tła, nasza aplikacja musi wywołać na początku funkcję CoInitialize, a na końcu funkcję CoUninitialize.

Omówimy na koniec jeszcze jedną ważną rzecz, a mianowicie sortowanie pól. Aby posortować pola musimy najpierw zdefiniować własną funkcję porównującą dwa elementy:

Funkcja strcmp porównuje dwa napisy z uwzględnieniem wielkości znaków i zwraca 0 gdy są napisy równe, 1 gdy napis pierwszy jest większy od drugiego lub -1 w przypadku gdy drugi napis jest większy od drugiego. My chcemy posortować pola w kierunku malejącym, więc musimy zmienić znak wyniku funkcji strcmp. Parametry lParam1 i lParam2 są to zdefiniowane przez nas informacje, które ustawiliśmy w polu lParam podczas dodawania nowych pozycji. Parametr lParamSort zawiera dodatkowe informacje przekazywane podczas wywoływania funkcji SendMessage:

Jeżeli jest coś, co jeszcze chcecie wiedzieć, a ja o tym nie wspomniałem, piszcie na maila.

Autor: krajew4

Załączniki