Часть 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;» активной (то есть убрать комментарий «//»), то соответствующие фоны рисунков станут прозрачными и мы получим:
***
Оставшиеся свойства применяются значительно реже и будут рассмотрены в следующей статье.