Советы по Delphi

         

Рисование TOutline


...возможно, но не так просто. Чтобы сделать это, вам нужно воспользоваться "Owner Draw" (рисование от владельца) outline. В обработчике события Outline OnDrawItem вам необходимо будет вывести ваше изображение и текст. Вроде бы ничего сложного, но реально вы столкнетесь с проблемой вычисления отступа для рисования дерева и прочее. Есть еще пара ошибок и нештатных ситуаций, с которыми вам наверняка придется иметь дело, если выберете такой способ рисования дерева.

Вот кусок кода из обработчика события OnDrawItem, который рисует для узла дерева иконку и сопровождающий ее текст. Код обработки растрового изображения, вероятно, может быть улучшен, поскольку у меня нет достаточного опыта работы с графикой Windows. В приведенном ниже примере olnOutline - это мой компонент outline, а bmpBitMap - мое растровое изображение.

    {Получаем индекс outline. Параметр DrawItem Index является просто номером строки, не принимающим во внимание свернутые узлы } lIndex := GetItem(Rect.Left, Rect.Top);
Offset := 2;  {Определяем расстояние между изображением и текстом}
with olnOutline do begin with Canvas do

begin
{Отступ изображения базируется на уровне Level узла OutlineNode} Inc(Rect.Left, Offset + (ItemHeight * (Items[lIndex].Level -1)));
{Копируем изображение } BrushCopy(Bounds(Rect.Left, Rect.Top, bmpBitMap.Width, bmpBitMap.Height), bmpBitMap, Bounds(0, 0, bmpBitMap.Height, bmpBitMap.Width), bmpBitMap.TransparentColor);
{Выводим текст справа от изображения} Inc(Rect.Left,bmpBitMap.Width + Offset); TextOut(Rect.Left, Rect.Top, Items[lIndex].Text); end; {with Canvas} end; {with Outline}

Примечание:
Это кусок кода из одного моего большоего проекта, и в нем еще встречается всякий хлам (код необходимо немного подправить). Например, существует проблема перерисовки, если во время выполнения приложения вы изменяете ширину Outline. Я полагаю, что это может случиться, если будет выключена горизонтальная полоса прокрутки. Во всяком случае проблема в том, что Rect, передаваемый в обработчик события OnDrawItem, содержит ширину на момент, предшествующий изменению размера Outline. Это можно обойти, используя ширину Outline для вычисления правильного размера Rect, а не использования значения, поставляемого Delphi.

Этот код НЕ рисует дерево. В свое время я подумывал о том, чтобы позаимствовать код непосредственно из VCL, но к сожалению (а может и к счастью), этот код оказался недоступен. [001944]



Содержание раздела