Мне необходимо было изменить поведение компонента по части его отрисовки, к примеру, мне нужно было позволить пользователю выделить несколько значений и покрасить их в другой цвет. Я с удивлением обнаружил, что использование функции GetItem для определения отрисовываемой строки на редкость просто и понятно. Прежде же для этой цели я создавал цикл, вылавливал из всех индексов нужный и затем передавал его процедуре. Но в случае с множественным выбором это становилось медленным, неуклюжим и запутанным.
Ниже я разместил пример такой программы. Она позволяет рисовать символы плюсы/минусы плюс сам текст. Я также включил в нее код для создания, загрузки и освобождения иконок с символами плюса и минуса.
procedure TForm1.FormCreate(Sender: TObject);
begin
BitmapPlus :=TBitmap.Create;
BitmapPlus.LoadFromFile('c:\delphi\images\default\outplus.bmp');
BitmapMinus:= TBitmap.Create;
BitmapMinus.LoadFromFile('c:\delphi\images\default\outminus.bmp');
end;
procedure TForm1.FormDestroy(Sender: TObject); begin BitMapPlus.Destroy; BitMapMinus.Destroy; end; procedure TForm1.Outline1DrawItem(Control:TWinControl; Index:Integer; Rect:TRect; State:TOwnerDrawState); var iLeft, iht: integer; s: string; NodeInView: TOutlineNode; col: TColor; {Примечание: BitMapvariables BitMapPlus и .. Минус объявлены глобально и грузятся при создании формы} begin with (Control as TOutline).Canvas do begin {рисуем на холсте элемента управления, не на форме} IndexInFull := outline1.getitem(rect.left+1,rect.top+1); NodeInView := Outline1.Items[IndexInFull]; Font := Outline1.Font; iLeft := Rect.Left; iht := Outline1.ItemHeight; inc(iLeft, iht*(NodeInView.level-1)); s := NodeInView.Text; Col := clWindow; Font.Color := clWindowText; Brush.Color := col; FillRect(Rect); { очищаем прямоугольник } if NodeInView.HasItems and not NodeInView.Expanded then {Draw(iLeft,Rect.Top, BitmapPlus)} BrushCopy(Bounds(iLeft+1,Rect.Top+1,iht-2,iht-2),BitMapPlus, Bounds(0,0,BitMapPlus.Width,BitMapPlus.Height), BitMapPlus.TransparentColor); if NodeInView.Expanded and NodeInView.HasItems then BrushCopy(Bounds(iLeft+1,Rect.Top+1,iht-2,iht-2),BitMapMinus, Bounds(0,0,BitMapMinus.Width,BitMapMinus.Height), BitMapMinus.TransparentColor); if Copy(NodeInView.Text,Length(NodeinView.Text),1)='y' then Col := clAqua; if Outline1.SelectedItem = IndexInFull then begin Col := clHighlight; Font.Color := clHighlightText end; Brush.Color := col; inc(ILeft,iht); TextOut(iLeft, Rect.Top, s); end; end; |
- David E. Scheim [000783]