Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Полигон
  
 

Фильтр по датам

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  12:04[Войти] | [Зарегистрироваться]

Компонент-потомок TListView с возможностью показа стрелочки в заголовке (как у Проводника Windows)

Дмитрий Савченко
дата публикации 23-06-2008 10:04

Компонент-потомок TListView с возможностью показа стрелочки в заголовке (как у Проводника Windows)

При работе над одним проектом мне понадобилось в заголовке компонента TListView отображать стрелочку, указывающую направление сортировки. Стандартный компонент такой возможности не предоставлял. Первым делом я обратился к поиску на Круглом столе, но не смог найти там подсказки, как такое реализовать. Многочисленные поиски в Сети позволили найти только один бесплатный потомок TListView с исходниками, умеющий в числе прочего и рисовать нужную стрелку (Об этом компоненте будет упомянуто чуть ниже). "Подсмотрев" реализацию прорисовки в этом компоненте я и написал свой TatwListView.

Использование компонента

Итак, TatwListView — прямой потомок класса TListView, в котором добавлено лишь одно опубликованное свойство:

{тип стрелки вверх-вниз}
TArrowType = (atUp, atDown);

{тип нового свойства компонента}
TArrowOptions = record
  SortColumnIndex: Integer;
  ArrowType: TArrowType;
end;

{само свойство}
property ArrowOptions: TArrowOptions;

Здесь, думаю, все понятно. Программист изменяет это свойство в любом месте кода — и нужная стрелочка отображается в нужной колонке. Если ArrowOptions.SortColumnIndex имеет отрицательное значение, то стрелка не отображается вообще. ArrowOptions.ArrowType имеет по умолчанию значение atUp.

Как это было сделано

Я не буду сдесь переписывать исходник компонента — все это можно посмотреть в прилагаемых файлах с комментариями. Опишу только ту часть кода, где непосредственно прорисовывается стрелка.

Но вначале следует заметить, что, начиная с Windows XP, ОС сама умеет рисовать стрелочки. Поэтому для XP и выше достаточно только указать системе, где ее рисовать. А вот для более старых версий Windows нарисовать стрелочку придется самим. Многие, возможно, скажут, что тогда проще для любой версии ОС включая XP и Vista осуществлять собственную прорисовку, но у меня есть на это пара возражений:

  1. Компонент TListView является надстройкой над стандартным объектом Windows. Поэтому весь функционал (и даже больше, как и в нашем случае), заложен в операционной системе, которая все же лучше знает как и где рисовать ту или иную часть объекта. Не очень рационально, по-моему учить систему делать то, что она и так умеет.
  2. Начиная с XP, Windows можно украсить (хотя, может наоборот, изуродовать) кучей разнообразных стилей, и никто не может знать, как в таком-то стиле будет выглядеть наша собственная стрелка. А в Vista эта стрелка вообще рисуется не справа от текста, а сверху, точно посередине колонки. А ведь мы хотим, чтобы было "также как в Проводнике".

Поэтому, компонент содержит два приватных метода SetColumnArrow и SetColumnArrowNonXP, которые и отвечают за установку стрелки. Вот их код:

procedure TatwListView.SetColumnArrow(ColumnIndex: Integer);
var
 HeaderHndl: HWND;
 Item: THDItem;
begin
 {получаем дескриптор заголовка нашего ListView'а}
 HeaderHndl := ListView_GetHeader(Handle);
 FillChar(Item, SizeOf(Item), 0);
 {значение этого оператора см. в справке от Microsoft}
 Item.Mask := HDI_FORMAT;
 {получаем информацию об указанной колонке в заголовке для дальнейшего ее изменения}
 Header_GetItem(HeaderHndl, ColumnIndex, Item);
 if (ColumnIndex = FArrowOptions.SortColumnIndex) then
 begin
  {предварительно убираем обе стрелки из флагов параметра fmt}
  Item.fmt:= Item.fmt and not (HDF_SORTDOWN or HDF_SORTUP);
  {указываем системе прорисовывать необходимую стрелку добавлением соотв. флага}
  if FArrowOptions.ArrowType = atUp then
   Item.fmt:= Item.fmt or HDF_SORTUP
  else
   Item.fmt:= Item.fmt or HDF_SORTDOWN;
 end
 {на этой колонке не надо рисовать стрелку - сообщаем об этом системе}
 else
  Item.fmt := Item.fmt and not({HDF_BITMAP or HDF_BITMAP_ON_RIGHT or} HDF_SORTDOWN 
  or HDF_SORTUP);

 {применяем установленные атрибуты - система сама нарисует колонку}  
 Header_SetItem(HeaderHndl, ColumnIndex, Item);
end;

procedure TatwListView.SetColumnArrowNonXP(ColumnIndex: Integer);
var
 hdr: HWND;
 Item: THDItem;
begin
 {здесь все так же как и в SetColumnArrow - см. выше}
 hdr := Listview_GetHeader(Handle);
 FillChar(Item, sizeof(Item), 0);
 Item.Mask := HDI_FORMAT;
 Header_GetItem(hdr, ColumnIndex, Item);
 if (ColumnIndex = FArrowOptions.SortColumnIndex) then
 begin
  {рисуем битмап - этот код прорисовки был заимствован из TListViewEx}
  Item.Mask := Item.Mask or HDI_BITMAP;
  Item.fmt  := Item.fmt  or HDF_BITMAP or HDF_BITMAP_ON_RIGHT;
  if FArrowOptions.ArrowType = atUp then
   Item.hbm:= FUpArrow.Handle
  else
   Item.hbm := FDownArrow.Handle;
 end
 else
  Item.fmt := Item.fmt and not(HDF_BITMAP or HDF_BITMAP_ON_RIGHT);
 Header_SetItem(hdr, ColumnIndex, Item);
end;

Где и как вызываются эти методы смотрите в исходниках.

Использованные материалы

Компонент TListViewEx (http://home.hccnet.nl/p.zylstra). Я частично использовал код этого компонента. В Copyright части модуля ListViewEx.pas указано, что этот компонент бесплатен и может быть использован в коммерческих/некоммерческих целях.

Исходник компонента с примером использования


Смотрите также материалы по темам:
[TListView] [Изменение внешнего вида стандартных компонент]

 Обсуждение материала [ 06-09-2012 08:33 ] 22 сообщения
  
Время на сайте: GMT минус 5 часов

Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
Функция может не работать в некоторых версиях броузеров.

Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

 
© При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
Все используемые на сайте торговые марки являются собственностью их производителей.

Яндекс цитирования