1

我正在尝试创建一个带有图像的列表框。图片将从 TImage 组件中获取;我不想使用 TImageList,因为 TImage 可以处理很多图像类型(png、gif、jpg),而且我不必转换它来填充 Imagelist。

所以我已经将我的列表框样式设置为 lbOwnerDrawVariable 并且我正在尝试将 TImage 中的图像绘制到列表框中。我已将 Image1 的宽度和高度设置为 50,因为这是我希望图像在列表框中具有的大小。

这是我的代码:

procedure TForm2.listbox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
  CenterText: Integer;
begin
  listbox1.Canvas.FillRect(Rect);
  listbox1.Canvas.draw(rect.Left+4,rect.Top+4,image1.Picture.graphic);
  CenterText := (Rect.Bottom - Rect.top - listbox1.Canvas.TextHeight(text)) div 2;
  listbox1.Canvas.TextOut(Rect.left + 58, Rect.top + CenterText, listbox1.Items.Strings[index]);
end;

但是,它不是将图像放在每个列表框项中,而是在列表框本身内绘制了很多图像,其原始大小而不是 50 ......我的代码有什么问题?

在此处输入图像描述

4

1 回答 1

4

Image1.WidthImage1.HeightTImage控件的尺寸。它们与Image1.Picture.

您需要拉伸绘制图像或预缩放它。

只是一个非常快速和肮脏的例子:

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin

  if Control <> ListBox1 then
    Exit;

  if Index = -1 then
    Exit;

  var C := ListBox1.Canvas;

  C.Brush.Color := clWindow;
  C.Font.Color := clWindowText;
  C.FillRect(Rect);

  var R := Rect;
  var S := ListBox1.Items[Index];

  var G := Image1.Picture.Graphic;

  var scale := 1.0;

  if (G.Width > 0) and (G.Height > 0) then
  begin

    var xscale := R.Width / G.Width;
    var yscale := R.Height / G.Height;
    scale := Min(xscale, yscale);

    R.Width := Round(G.Width * scale);
    R.Height := Round(G.Height * scale);

    C.StretchDraw(R, G);

  end;

  R := Rect;
  R.Left := R.Left + Round(G.Width * scale) + C.TextWidth('0');
  C.TextRect(R, S, [tfSingleLine, tfVerticalCenter, tfEndEllipsis]);

end;

带有 TImage 和所有者绘制的列表框的表单的屏幕截图,该列表框使用 TImage 的图形作为每个项目的图标。

于 2022-01-25T18:50:30.633 回答