Дмитрий Савченко дата публикации 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 осуществлять собственную прорисовку, но у меня есть на это пара возражений:
- Компонент TListView является надстройкой над стандартным объектом Windows. Поэтому весь функционал (и даже больше, как и в нашем случае), заложен в операционной системе, которая все же лучше знает как и где рисовать ту или иную часть объекта. Не очень рационально, по-моему учить систему делать то, что она и так умеет.
- Начиная с XP, Windows можно украсить (хотя, может наоборот, изуродовать) кучей разнообразных стилей, и никто не может знать, как в таком-то стиле будет выглядеть наша собственная стрелка. А в Vista эта стрелка вообще рисуется не справа от текста, а сверху, точно посередине колонки. А ведь мы хотим, чтобы было "также как в Проводнике".
Поэтому, компонент содержит два приватных метода SetColumnArrow и SetColumnArrowNonXP, которые и отвечают за установку стрелки. Вот их код:
procedure TatwListView.SetColumnArrow(ColumnIndex: Integer);
var
HeaderHndl: HWND;
Item: THDItem;
begin
HeaderHndl := ListView_GetHeader(Handle);
FillChar(Item, SizeOf(Item), 0);
Item.Mask := HDI_FORMAT;
Header_GetItem(HeaderHndl, ColumnIndex, Item);
if (ColumnIndex = FArrowOptions.SortColumnIndex) then
begin
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_SORTDOWN
or HDF_SORTUP);
Header_SetItem(HeaderHndl, ColumnIndex, Item);
end;
procedure TatwListView.SetColumnArrowNonXP(ColumnIndex: Integer);
var
hdr: HWND;
Item: THDItem;
begin
hdr := Listview_GetHeader(Handle);
FillChar(Item, sizeof(Item), 0);
Item.Mask := HDI_FORMAT;
Header_GetItem(hdr, ColumnIndex, Item);
if (ColumnIndex = FArrowOptions.SortColumnIndex) then
begin
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 сообщения |