How to put an image (e.g sort arrow) on a listview column header (Views: 712)
Problem/Question/Abstract: When sorting TListViews it is good practise to show which column is sorted and in which direction. Answer: Add this to your form: uses commctrl; 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: var Ascending: boolean; procedure TForm1.ListViewColumnClick(Sender: TObject; Column: TListColumn); var i: integer; begin // Toggle column Tag Column.Tag := 1 - Column.Tag; // 0 -> 1 ; 1 -> 0 // Determine sort order based on the value of the Tag Ascending := Column.Tag = 1; // This loop displays the icon in the selected column. for i := 0 to ListView.Columns.Count - 1 do SetColumnImage(ListView, i, Column.Tag, i = Column.Index); // The CustomSort function is not covered in this // article but is explained elsewhere in Delphi Knowledge Base TListView(Sender).CustomSort(@SortByColumn, 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. |