Здраствуйте.
Подскажите пожалуйста, каким образом можно добавить иконку сортировки в заголовок колонки ListView.
Я ее добавлю так, но при изменении размеров колонки эта иконка исчезает.
handleheader := ListView_GetHeader(ListView1.Handle);
hdi.Mask:=HDI_FORMAT;
Header_GetItem(handleheader,0,hdi);
hdi.fmt:=hdi.fmt or (HDF_BITMAP or HDF_BITMAP_ON_RIGHT);
hdi.Mask := hdi.mask or HDI_BITMAP;
hdi.hbm := Bitmap.Handle;
Header_SetItem(handleheader,0,hdi);
Заранее спасибо.
Re: Иконка сортировки в заголовке колонки ListView?
Здравствуйте, Иванов Иван Петрович, Вы писали:
ИИП>Я ее добавлю так, но при изменении размеров колонки эта иконка исчезает.
Недавно занимался аналогичными поисками и с тем же результатом. Нарыто было 2 решения:
1. Использовать в качестве иконки ImageList из SmallImages (с учетом "последствий" в виде отступов и попыток рисования иконок в строках). Мне не подошел — я еще и CheckBox-ы использую, а Indent==-1 сдвигает всю строку вместе с чекбоксом
2. Вышеуказанный вариант. С поправкой — надо проверять валидность хендла битмапа — иначе ващще ничего не рисуется. Рытье по гуглу и мелкософту показало: надо реагировать на событие смены размеров колонок и задавать картинку заново. В WinXP (Common controls 6.0 + manifest) можно использовать встроенные стрелки — там соответствующие флаги появились...
Ну и можно полностью рисовать самому (что кстати судя по fmt / mask делает Дельфи при использовании ListView)
ЗЫ: У себя пока не сделал никак — забыл Видимо, буду ловить изменения размеров...
---
wbr, Alexander Voronin
mailto:
Re: Иконка сортировки в заголовке колонки ListView?
Глянул ща в исходник comctrls.pas — надо перекрыть процедуру UpdateColumn(Index) — там все флаги и сбрасываются
Буду пробовать — вроде все использованные там приватные поля доступны через проперти...
Встречный вопрос: Что делать с прозрачностью — сейчас искусственно рисую нужный битмап с прозрачностью в текущие системные цвета 3D объектов — как-то некузяво это — и потом использую перерисованную картинку с "правильным" фоном...
---
wbr, Alexander Voronin
mailto:
Re[2]: Иконка сортировки в заголовке колонки ListView?
Здравствуйте, Александр Воронин,
Спасибо за ответ.
Вы писали: АВ> надо реагировать на событие смены размеров колонок и задавать картинку заново.
Я так и сделал. Отлавливаю событие окончания перемещения колонки (именно тогда она стерается) и рисую заново.
procedure TForm1.WMNotify(var Msg: TWMNotify);
begin
inherited;
case Msg.NMHdr^.code of
HDN_ENDTRACK:
begin//смотрю на какой колонке была картинка и рисую заново.end;
end;
end;
АВ> В WinXP (Common controls 6.0 + manifest) можно использовать встроенные стрелки — там соответствующие флаги появились...
Может подскажещь как там это можно сделать.
Заранее спасибо.
Re[2]: Иконка сортировки в заголовке колонки ListView?
Здравствуйте, Александр Воронин, Вы писали:
АВ>Глянул ща в исходник comctrls.pas — надо перекрыть процедуру UpdateColumn(Index) — там все флаги и сбрасываются
Хороший вариант, надо попробовать.
АВ>Встречный вопрос: Что делать с прозрачностью — сейчас искусственно рисую нужный битмап с прозрачностью в текущие системные цвета 3D объектов — как-то некузяво это — и потом использую перерисованную картинку с "правильным" фоном...
На счет прозрачности подсказать, к сожалению немого.
Re[3]: Иконка сортировки в заголовке колонки ListView?
А вот это у меня не работает
Правда, я не с формы ловлю, а из наследника CustomListView. Просабклассил Header по аналогии с ListView,
при изменении размеров Header-у шлются HDM_SETITEMW — там подменяю флаги. Это работает только при изменении размера и только для изменяемого столбца. Дальше пытаюсь отловить HDN_ITEMCLICK в ListView — никуда не доходит. Придется вернуться к временно отключенному обработчику OnClick для реакции на нажатие.
ИИП>Может подскажещь как там это можно сделать.
С манифестом не помню — поиск рулит... Где-то был пример этого xml файлика. Штатно запихать его в ресурсы дельфей наверно не выйдет — надо класть рядом или компилить .res чем-то, что понимает тип ресурса XML (VisualStutio например А константы —
процедура "инициализации" — зовется при запуске и по ColClick для изменения направления сортировки и рисунка. Выставляет картинку или флаг стрелки в зависимости от версии ComCtl32.dll
обработчик WMParentNotify — сабклассим окно Header. Причем не первый пршедший hWnd, как в оригинальном ListView, а второй.
Оконная процедура для Header. Ловит HDM_SETITEM(W), HDM_INSERTITEM(W). Сбрасывает fmt == HDF_IMAGE (см. далее), выставляет нужную картинку или флаг.
Create/Destroy — обработка переменных сабклассинга
Примечание1: в VCL есть бага — в том самом UpdateColumn(index) — выставляется флаг LVCF_IMAGE независимо от ImageIndex — это приводит к "падению" в kernel32.dll при добавлении манифеста. Обходной путь — при добавлении Column ставим ему ImageIndex <> -1. А в оконной процедуре убираем HDF_IMAGE . Эту бяку надо делать у _всех_ контролов на основе CustomListView (если их создатель заранее не позаботился об этой баге)
Примечание2: Встроенные в ComCtl32 стрелки также сбрасываются при ресайзе — не забываем выставтиь в оконной процедуре
Примечание3:
HDF_SORTUP = $0400;
HDF_SORTDOWN = $0200;
---
wbr, Alexander Voronin
mailto:
Re[4]: Итого: Иконка сортировки в заголовке колонки ListVie
Здравствуйте, Александр Воронин, Вы писали:
ИИП>>Я так и сделал. Отлавливаю событие окончания перемещения колонки (именно тогда она стерается) и рисую заново. ИИП>>
...
private
WndMethod: TWndMethod;
procedure CheckMesg(var Msg: TMessage);
...
procedure TForm1.CheckMesg(var Msg: TMessage);
var
hdn: ^THDNotify;
begin
if Msg.Msg = WM_NOTIFY then
begin
hdn := Pointer(Msg.lParam);
if (hdn.hdr.code = HDN_ENDTRACKW) or (hdn.hdr.code = HDN_ENDTRACKA) then//здесь смотрим на какой колонке была картинка и рисую заново.else
WndMethod(Msg);
end
else
WndMethod(Msg);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
WndMethod := ListView1.WindowProc;
ListView1.WindowProc := CheckMesg;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ListView1.WindowProc := WndMethod;
WndMethod:=nil;
end;
Re[5]: Иконка сортировки в заголовке колонки ListView?
Здравствуйте, Иванов Иван Петрович, Вы писали:
ИИП>Попробуй так: ИИП>
ИИП>...
ИИП> private
ИИП>
Это же сабклассить еще и ListView Лень С меня хватает его Header-а...
Принцип тот же _НО_ у меня не форма а наследник от ListView — самостоятельный контрол, не хочу завязываться на форму. Кто-то там раньше ловит это событие и не пропускает ниже. Ну и ладно — работает и так, а разбираться уже некогда
Собственно, я даже сэкономил — просто подменяю значения в Message прежде чем отдать его на исполнение