Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Значок направления сортировки в ListView


Автор: v258 13.2.2017, 17:57
Делаю программу, в которой получаю список файлов в ListView. Сделал в числе прочего сортировку по столбцам в режиме vsReport. Все работает, но встал вопрос - как добавить в заголовок столбца иконку стрелочки, указывающей направление сортировки. ListView.Columns[0].ImageIndex не подходит, т.к. уже подключен imageList с системными иконками для отображения значков файлов. Добавить в него свои иконки не получится, т.к. его содержимое меняется динамически в процессе работы программы. 

Как быть?

Автор: v258 14.2.2017, 13:08
Мда, Винград уже не тот...  smile 

Для интересующихся рассказываю, как можно сделать - нужно подключить отдельный imagelist для заголовков
Код

procedure SetHeaderImages(ListView: TCustomListView;
  Images: TCustomImageList);
var
  wnd : HWND;
begin
  wnd := FindWindowEx(ListView.Handle,0,'SysHeader32',nil);
  if wnd <> 0 then
  begin
    Header_SetImageList(wnd,Images.Handle);
  end;
end;

функция Header_SetImageList прописана в модуле CommCtrl

Взято отсюда - http://vicking.narod.ru/articles/listview.htm

Автор: -Сергей- 12.4.2017, 20:34
Удалите пожалуйста этот пост.

Автор: v258 12.4.2017, 20:46
Почему? Решение вопроса не приветствуется? 

Автор: ZBugz 13.4.2017, 07:15
Цитата(v258 @ 12.4.2017,  20:46)
Почему? Решение вопроса не приветствуется?

Это он наверное запостил не туда, вот и просит удалить свой пост.
А решение хорошее  smile 

Автор: -Сергей- 13.4.2017, 17:20
Да, это я не туда запостил.
Кстати, заголовок не так обычно находят. Для этого есть специальное сообщение LVM_GETHEADER. Можно воспользоваться функцией ListView_GetHeader, которая его и отсылает.
Можно еще обойтись без Imagelist, устанавливать системный значок сортировки, но придется писать больше кода.  Есть один нюанс, при изменении размера столбца иконка слетает. Чтобы этого не произошло надо отловить HDN_ENDTRACK который приходит с WM_NOTIFY, сабклассим ListView и перекрываем WMNotify.
Возьмите на вооружение:
Код

uses ... CommCtrl, XPMan;

type
  TListView = class(ComCtrls.TListView)
  private
    FHeaderHandle: HWND;
    procedure WMNotify(var AMessage: TWMNotify); message WM_NOTIFY;
  protected
    procedure CreateWnd; override;
  end;
...
const
  LVS_EX_DOUBLEBUFFER = $10000;
  LVS_EX_BORDERSELECT = $8000;
  HDF_SORTUP = $0400;
  HDF_SORTDOWN =$0200;
...
procedure TForm1.ListView1ColumnClick(Sender: TObject; Column: TListColumn);
var
  Header: HWND;
  Item: THDItem;
  I: Integer;
begin
  Header := ListView_GetHeader(ListView1.Handle);
  ZeroMemory(@Item, SizeOf(Item));
  Item.Mask := HDI_FORMAT;
  Header_GetItem(Header, Column.Index, Item);

  if (Item.fmt and HDF_SORTUP) = HDF_SORTUP then
  begin
    Item.fmt := Item.fmt and not (HDF_SORTUP or HDF_SORTDOWN); // remove both flags
    for I := 0 to ListView1.Columns.Count - 1 do Header_SetItem(Header, i, Item);
    Item.fmt := Item.fmt or HDF_SORTDOWN; //include the sort descending flag
    Header_SetItem(Header, Column.Index, Item);
  end
  else
  if (Item.fmt and HDF_SORTDOWN) = HDF_SORTDOWN then
  begin
    Item.fmt := Item.fmt and not (HDF_SORTUP or HDF_SORTDOWN); //remove both flags
    for I := 0 to ListView1.Columns.Count - 1 do Header_SetItem(Header, i, Item);
    Item.fmt := Item.fmt or HDF_SORTUP; //include the sort ascending flag
    Header_SetItem(Header, Column.Index, Item);
  end
  else
  begin
    Item.fmt := Item.fmt and not (HDF_SORTUP or HDF_SORTDOWN); //remove both flags
    for I := 0 to ListView1.Columns.Count - 1 do Header_SetItem(Header, i, Item);
    Item.fmt := Item.fmt or HDF_SORTDOWN; //include the sort ascending flag
    Header_SetItem(Header, Column.Index, Item);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  dwStyle: DWORD;
begin
  dwStyle:= ListView_GetExtendedListViewStyle(ListView1.Handle);
  dwStyle:= dwStyle or LVS_EX_DOUBLEBUFFER;
  ListView_SetExtendedListViewStyle(ListView1.Handle, dwStyle);
end;

{ TListView }

procedure TListView.CreateWnd;
begin
  inherited;
  FHeaderHandle := ListView_GetHeader(Handle);
end;

procedure TListView.WMNotify(var AMessage: TWMNotify);
begin
  case AMessage.NMHdr.code of
    HDN_ENDTRACKA, HDN_ENDTRACKW: AMessage.Result := 0;
  else
    inherited;
  end;
end;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)