Иконка сортировки в заголовке колонки ListView?
От: Иванов Иван Петрович  
Дата: 03.05.05 17:41
Оценка:
Здраствуйте.
Подскажите пожалуйста, каким образом можно добавить иконку сортировки в заголовок колонки 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?
От: Александр Воронин Россия [70620598]
Дата: 07.05.05 15:47
Оценка:
Здравствуйте, Иванов Иван Петрович, Вы писали:

ИИП>Я ее добавлю так, но при изменении размеров колонки эта иконка исчезает.


Недавно занимался аналогичными поисками и с тем же результатом. Нарыто было 2 решения:

1. Использовать в качестве иконки ImageList из SmallImages (с учетом "последствий" в виде отступов и попыток рисования иконок в строках). Мне не подошел — я еще и CheckBox-ы использую, а Indent==-1 сдвигает всю строку вместе с чекбоксом

2. Вышеуказанный вариант. С поправкой — надо проверять валидность хендла битмапа — иначе ващще ничего не рисуется. Рытье по гуглу и мелкософту показало: надо реагировать на событие смены размеров колонок и задавать картинку заново. В WinXP (Common controls 6.0 + manifest) можно использовать встроенные стрелки — там соответствующие флаги появились...

Ну и можно полностью рисовать самому (что кстати судя по fmt / mask делает Дельфи при использовании ListView)

ЗЫ: У себя пока не сделал никак — забыл Видимо, буду ловить изменения размеров...
---
wbr, Alexander Voronin
mailto:
Re: Иконка сортировки в заголовке колонки ListView?
От: Александр Воронин Россия [70620598]
Дата: 07.05.05 16:14
Оценка:
Здравствуйте, Иванов Иван Петрович, Вы писали:

Глянул ща в исходник comctrls.pas — надо перекрыть процедуру UpdateColumn(Index) — там все флаги и сбрасываются

Буду пробовать — вроде все использованные там приватные поля доступны через проперти...

Встречный вопрос: Что делать с прозрачностью — сейчас искусственно рисую нужный битмап с прозрачностью в текущие системные цвета 3D объектов — как-то некузяво это — и потом использую перерисованную картинку с "правильным" фоном...

---
wbr, Alexander Voronin
mailto:
Re[2]: Иконка сортировки в заголовке колонки ListView?
От: Иванов Иван Петрович  
Дата: 07.05.05 18:45
Оценка:
Здравствуйте, Александр Воронин,
Спасибо за ответ.

Вы писали:
АВ> надо реагировать на событие смены размеров колонок и задавать картинку заново.

Я так и сделал. Отлавливаю событие окончания перемещения колонки (именно тогда она стерается) и рисую заново.
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?
От: Иванов Иван Петрович  
Дата: 07.05.05 18:55
Оценка:
Здравствуйте, Александр Воронин, Вы писали:

АВ>Глянул ща в исходник comctrls.pas — надо перекрыть процедуру UpdateColumn(Index) — там все флаги и сбрасываются


Хороший вариант, надо попробовать.

АВ>Встречный вопрос: Что делать с прозрачностью — сейчас искусственно рисую нужный битмап с прозрачностью в текущие системные цвета 3D объектов — как-то некузяво это — и потом использую перерисованную картинку с "правильным" фоном...


На счет прозрачности подсказать, к сожалению немого.
Re[3]: Иконка сортировки в заголовке колонки ListView?
От: Александр Воронин Россия [70620598]
Дата: 07.05.05 19:02
Оценка:
Здравствуйте, Иванов Иван Петрович, Вы писали:


ИИП>Я так и сделал. Отлавливаю событие окончания перемещения колонки (именно тогда она стерается) и рисую заново.

ИИП>
ИИП>procedure TForm1.WMNotify(var Msg: TWMNotify);
ИИП>


А вот это у меня не работает
Правда, я не с формы ловлю, а из наследника CustomListView. Просабклассил Header по аналогии с ListView,
при изменении размеров Header-у шлются HDM_SETITEMW — там подменяю флаги. Это работает только при изменении размера и только для изменяемого столбца. Дальше пытаюсь отловить HDN_ITEMCLICK в ListView — никуда не доходит. Придется вернуться к временно отключенному обработчику OnClick для реакции на нажатие.

ИИП>Может подскажещь как там это можно сделать.


С манифестом не помню — поиск рулит... Где-то был пример этого xml файлика. Штатно запихать его в ресурсы дельфей наверно не выйдет — надо класть рядом или компилить .res чем-то, что понимает тип ресурса XML (VisualStutio например А константы —

здесь

Подробнее не пробовал. И, видимо, в скором времени не буду Переписать UpdateItem не выйдет — там нет выртуальных процедур

О. Нашел файлик. Название должно быть "МояСуперПрограмма.exe.manifest" ^)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
    version="1.0.0.0"
    processorArchitecture="X86"
    name="Company.Product.Application"
    type="win32"
/>
<description>Application description.</description>
<dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            processorArchitecture="X86"
            publicKeyToken="6595b64144ccf1df"
            language="*"
        />
    </dependentAssembly>
</dependency>
</assembly>
---
wbr, Alexander Voronin
mailto:
Re[3]: Иконка сортировки в заголовке колонки ListView?
От: Александр Воронин Россия [70620598]
Дата: 07.05.05 19:27
Оценка:
Здравствуйте, Иванов Иван Петрович, Вы писали:


ИИП>Может подскажещь как там это можно сделать.


ХА! Манифест успешно подключен! %)
Берем файл с манифестом, создаем ресурсный скрипт

aaa.rc:
1 24 "имя_файла_манифеста"


натравливаем на него brcc32 — получаем .res
его подключаем в проекте — {$ aaa.res} и радуемся %)

Дальше, видимо, дело техники — проверить версию ComCtl32 — если >= 6 — использовать его константы...

ЗЫ: значения "1" и "24" обязательны (см. например здесь)
---
wbr, Alexander Voronin
mailto:
Re[3]: Итого: Иконка сортировки в заголовке колонки ListVie
От: Александр Воронин Россия [70620598]
Дата: 08.05.05 00:08
Оценка:
Здравствуйте, Иванов Иван Петрович, Вы писали:

В обчем что-то сделал (в т.ч. и с манифестом):


Примечание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
От: Иванов Иван Петрович  
Дата: 08.05.05 07:07
Оценка:
Спасибо.
Ценные вещи подсказал.
С манифестом уже попробовал, получилось отлично.
Re[4]: Иконка сортировки в заголовке колонки ListView?
От: Иванов Иван Петрович  
Дата: 08.05.05 14:08
Оценка:
Здравствуйте, Александр Воронин, Вы писали:

ИИП>>Я так и сделал. Отлавливаю событие окончания перемещения колонки (именно тогда она стерается) и рисую заново.

ИИП>>
ИИП>>procedure TForm1.WMNotify(var Msg: TWMNotify);
ИИП>>


АВ>А вот это у меня не работает


Попробуй так:
...
  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?
От: Александр Воронин Россия [70620598]
Дата: 08.05.05 14:19
Оценка:
Здравствуйте, Иванов Иван Петрович, Вы писали:

ИИП>Попробуй так:

ИИП>
ИИП>...
ИИП>  private
ИИП>

Это же сабклассить еще и ListView Лень С меня хватает его Header-а...

Принцип тот же _НО_ у меня не форма а наследник от ListView — самостоятельный контрол, не хочу завязываться на форму. Кто-то там раньше ловит это событие и не пропускает ниже. Ну и ладно — работает и так, а разбираться уже некогда
Собственно, я даже сэкономил — просто подменяю значения в Message прежде чем отдать его на исполнение
---
wbr, Alexander Voronin
mailto:
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.