Author: Tomas Rutkauskas
When sorting TListViews it is good practise to show which column is sorted and in
which direction.
Answer:
Add this to your form:
1 uses commctrl;
2 3 procedure TForm1.SetColumnImage(List: TListView; Column, Image: Integer; ShowImage:
4 Boolean);
5 var6 Align, hHeader: integer;
7 HD: HD_ITEM;
8 begin9 hHeader := SendMessage(List.Handle, LVM_GETHEADER, 0, 0);
10 with HD do11 begin12 case List.Columns[Column].Alignment of13 taLeftJustify: Align := HDF_LEFT;
14 taCenter: Align := HDF_CENTER;
15 taRightJustify: Align := HDF_RIGHT;
16 else17 Align := HDF_LEFT;
18 end;
19 20 mask := HDI_IMAGE or HDI_FORMAT;
21 22 pszText := PChar(List.Columns[Column].Caption);
23 24 if ShowImage then25 fmt := HDF_STRING or HDF_IMAGE or HDF_BITMAP_ON_RIGHT
26 else27 fmt := HDF_STRING or Align;
28 29 iImage := Image
30 31 end;
32 SendMessage(hHeader, HDM_SETITEM, Column, Integer(@HD));
33 end;
Images are taken from the SmallImages list. You should call this function for each
column, and set the ShowImage to TRUE for the column you sorted. You can do this in
the OnColumnClick() function:
34 var35 Ascending: boolean;
36 37 procedure TForm1.ListViewColumnClick(Sender: TObject; Column: TListColumn);
38 var39 i: integer;
40 begin41 // Toggle column Tag42 Column.Tag := 1 - Column.Tag; // 0 -> 1 ; 1 -> 043 // Determine sort order based on the value of the Tag44 Ascending := Column.Tag = 1;
45 46 // This loop displays the icon in the selected column.47 for i := 0 to ListView.Columns.Count - 1 do48 SetColumnImage(ListView, i, Column.Tag, i = Column.Index);
49 50 // The CustomSort function is not covered in this51 // article but is explained elsewhere in Delphi Knowledge Base52 TListView(Sender).CustomSort(@SortByColumn, Column.Index);
53 end;
Problem: Resizing the column header causes a WM_PAINT which will erase the image.
Solution: Override WM_PAINT and call SetColumnImage again from there. I used
TApplicationEvents component from delphi 5.
If someone knows a better solution please let me know.