Delphi. Компонент ComboBox. Код отрисовки строк.

Часть 4. Строки разной высоты.

В предыдущей части мы рассмотрели, как нарисовать строки, имеющие одинаковую высоту.

Теперь посмотрим, как нарисовать строки, высота которых должна быть разной. Например, во второй и четвёртой строках надо разместить картинки большей высоты, чем во всех остальных трёх.

Режим csOwnerDrawVariable 

Первое, что надо сделать, это задать свойству «Style» значение «csOwnerDrawVariable».

В этом режиме для каждой строки необходимо программно задавать свою высоту.

Это делается в обработчике событий «onMeasureItem», заголовок которого имеет вид:

procedure TForm1.ComboBox1MeasureItem(Control: TWinControl; Index: Integer; var Height: Integer);

Здесь параметры:

Index — номер строки;

var Height — параметр-переменная, содержащаю высоту строки.

Так как Height — параметр переменная, то мы можем как читать её значение, передаваемое в процедуру, так и устанавливать новое значение высоты строки.

Например, установим для строк 2 и 4 (соответственно, «Index» равен 1 и 3), высоту строки в 70 пикселей.

Задать высоту строк в ComboBox

Рассмотрим код обработчика:

procedure TForm1.ComboBox1MeasureItem(Control: TWinControl; Index: Integer; var Height: Integer);
begin
if (Index=1) or (Index=3) then Height:=70;
end;

Нарисовать строки.

Как и в случае со строками фиксированной высоты, отрисовку строк производим в обработчике «ComboBox1DrawItem»:

Проведём подготовительные манипуляции.

Во первых, введем дополнительные вспомогательные локальные перменные « var abmp:array[0..4] of Tbitmap; i:integer;»

Переменная «abmp» — массив хранения обектов типа «Tbitmap».

Во вторых, вместо метода отрисовки строк «ComboBox1.Canvas.Draw(Rect.Left,Rect.Top,bm);» используем метод «ComboBox1.Canvas.StretchDraw(rect, abmp[index]);»

Если первый метод выводит изображение в прямоугольник строки списка «как есть», то есть без преобразований, то второй метод вписывает изображение в прямоугольник «rect».

Код программы.

Подготовленные изображения будем хранить в массиве типа «Tbitmap». Для этого осуществим заполнение элементов массива объектами в цикле.

Далее заполним элементы массива конкретными изображениями.

Заполним строки «ComboBox» немаскированными изображениями.

procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TownerDrawState);
var abmp:array[0..4] of Tbitmap; i:integer;
begin
for i:=0 to 4 do
abmp[i]:=TBitmap.Create; //создаём объекты

//заполняем элементы массива изображениями
abmp[0].LoadFromFile(‘1.bmp’);
abmp[1].LoadFromFile(‘bmp1.bmp’);
abmp[2].LoadFromFile(‘2.bmp’);
abmp[3].LoadFromFile(‘bmp4.bmp’);
abmp[4].LoadFromFile(‘3.bmp’);

Разметим строку следующим образом.
1) Всё, что размещено в строке, вписывается в прямоугольник «rect».
2) Координата левой стороны прямоугольника — «rect.Left».
3) Координата правой стороны прямоугольника — «rect.Right».
4) Будем считать, что для вывода символов нам достаточно 60 пикселей.
5) Высота строки «Height» задаётся в обработчике события «ComboBox1MeasureItem»

rect.Right:=rect.Right-60; //координата правой стороны прямоугольника для вывода картинки. Таким образом формируем прямоугольник «rect», в который будет выведено изображение.

//abmp[index].Transparent:=true; //понадобится в дальнейшем, когда фон картинки сделаем прозрачным

if (Index=0) then
begin
ComboBox1.Canvas.Brush.Color:=clSkyBlue; //цвет фона первой строки
ComboBox1.Canvas.FillRect(Rect); //закрасить фон первой строки
abmp[index].TransparentColor:=clWhite; //транспорентный цвет первой строки (пикселы этого цвета будут закрашены цветом фона)
end;

//аналогично все остальные строки

if (Index=1) then
begin
ComboBox1.Canvas.Brush.Color:=clRed;
ComboBox1.Canvas.FillRect(Rect);
abmp[index].TransparentColor:=rgb(255,242,0);
end;

if (Index=2) then
begin
ComboBox1.Canvas.Brush.Color:=clblue;
ComboBox1.Canvas.FillRect(Rect);
abmp[index].TransparentColor:=clWhite;
end;

if (Index=3) then
begin
ComboBox1.Canvas.Brush.Color:=clgreen;
ComboBox1.Canvas.FillRect(Rect);
abmp[index].TransparentColor:=rgb(163,73,164);
end;

if (Index=4) then
begin
ComboBox1.Canvas.Brush.Color:=clgray;
ComboBox1.Canvas.FillRect(Rect);
abmp[index].TransparentColor:=clWhite;
end;
//рисуем изображение, вписывая его в границы прямоугольника «rect».
ComboBox1.Canvas.StretchDraw(rect, abmp[index]);
//выводим текст, начиная с семидесятой позиции.
ComboBox1.Canvas.TextOut(70,Rect.Top, ComboBox1.Items[index]);
end;

В результате будем иметь:

Если теперь сделать строку «//abmp[index].Transparent:=true;» активной (то есть убрать комментарий «//»), то соответствующие фоны рисунков станут прозрачными и мы получим:

***

Оставшиеся свойства применяются значительно реже и будут рассмотрены в следующей статье.

Обновлено: 14.07.2021 — 14:38

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *