Title: How to put an image (e.g sort arrow) on a listview column header
Question: When sorting TListViews it is good practise to show which column is sorted and in which direction.
Answer:
This trick is balantly stolen from www.delphipages.com and was originally posted by TaubMic from swissdelphicenter.ch.
Add this to your form:
procedure TForm1.SetColumnImage( List: TListView; Column, Image: Integer;
ShowImage: Boolean);
var
Align,hHeader: integer;
HD: HD_ITEM;
begin
hHeader := SendMessage(List.Handle, LVM_GETHEADER, 0, 0);
with HD do
begin
case List.Columns[Column].Alignment of
taLeftJustify: Align := HDF_LEFT;
taCenter: Align := HDF_CENTER;
taRightJustify: Align := HDF_RIGHT;
else
Align := HDF_LEFT;
end;
mask := HDI_IMAGE or HDI_FORMAT;
pszText := PChar(List.Columns[Column].Caption);
if ShowImage then
fmt := HDF_STRING or HDF_IMAGE or HDF_BITMAP_ON_RIGHT
else
fmt := HDF_STRING or Align;
iImage := Image;
end;
SendMessage(hHeader, HDM_SETITEM, Column, Integer(@HD));
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:
procedure TForm1.ListView1ColumnClick(Sender: TObject;
Column: TListColumn);
var
i : integer;
begin
// The CustomSort function is not covered in this
// article but is explained elsewhere in delphi3000.com
CustomSort( @CustomSortProc, Column.Index );
// This loop displays the icon in the selected column.
for i := 0 to ListView1.Columns.Count-1 do
SetColumnImage( ListView1, i, 0, i = Column.Index );
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.