delphi - 如何在Delphi XE中为TListview设置背景图片?

标签 delphi delphi-xe tlistview

如何在 Delphi XE 中为 TListview 设置背景图像?

我想制作一个像Windows资源管理器一样的应用程序。

最佳答案

为了在 ListView 中设置水印,您需要使用 LVM_SETBKIMAGE消息,并且您需要覆盖 TListView 的默认 WM_ERASEBKGND 消息。 ListView 拥有位图句柄的所有权,因此您需要使用 TBitmap 的 ReleaseHandle,而不仅仅是 Handle

如果您希望它与左上角对齐,而不是像资源管理器那样与右下角对齐,请使用 LVBKIF_SOURCE_HBITMAP 而不是 LVBKIF_TYPE_WATERMARK 作为 ulFlags > 值。

uses
  CommCtrl, ...;

type
  TListView = class(ComCtrls.TListView)
  protected
    procedure WndProc(var Message: TMessage);
      override;
  end;

  TForm4 = class(TForm)
    ListView1: TListView;
    procedure FormCreate(Sender: TObject);
  end;

procedure TListView.WndProc(var Message: TMessage);
begin
  if Message.Msg = WM_ERASEBKGND then
    DefaultHandler(Message)
  else
    inherited WndProc(Message);
end;

procedure TForm4.FormCreate(Sender: TObject);
var
  Img: TImage;
  BkImg: TLVBKImage;
begin
  FillChar(BkImg, SizeOf(BkImg), 0);
  BkImg.ulFlags := LVBKIF_TYPE_WATERMARK;
  // Load image and take ownership of the bitmap handle
  Img := TImage.Create(nil);
  try
    Img.Picture.LoadFromFile('C:\Watermark.bmp');
    BkImg.hbm := Img.Picture.Bitmap.ReleaseHandle;
  finally
    Img.Free;
  end;
  // Set the watermark
  SendMessage(ListView1.Handle, LVM_SETBKIMAGE, 0, LPARAM(@BkImg));
end;

拉伸(stretch)水印

ListView 本身不支持在整个背景上拉伸(stretch)位图。为此,您需要自己执行 StretchBlt 来响应 WM_ERASEBKGND。

type
  TMyListView = class(TListView)
  protected
    procedure CreateHandle; override;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure WMEraseBkgnd(var Msg: TWMEraseBkgnd); message WM_ERASEBKGND;
  public
    Watermark: TBitmap;
  end;

procedure TMyListView.CreateHandle;
begin
  inherited;
  // Set text background color to transparent
  SendMessage(Handle, LVM_SETTEXTBKCOLOR, 0, CLR_NONE);
end;

procedure TMyListView.CreateParams(var Params: TCreateParams);
begin
  inherited;
  // Invalidate every time the listview is resized
  Params.Style := Params.Style or CS_HREDRAW or CS_VREDRAW;
end;

procedure TMyListView.WMEraseBkgnd(var Msg: TWMEraseBkgnd);
begin
  StretchBlt(Msg.DC, 0, 0, Width, Height, Watermark.Canvas.Handle,
    0, 0, Watermark.Width, Watermark.Height, SrcCopy);
  Msg.Result := 1;
end;

关于delphi - 如何在Delphi XE中为TListview设置背景图片?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3987522/

相关文章:

Delphi:当PChar指向的字符串变量改变后,临时PChar是否保证具有相同的值?

multithreading - 关闭申请后的文件复制

delphi - Delphi DFM 文件中的奇怪[数字] - 起源和必要性?

android - 如何使用Delphi 10在android中录制后台声音

delphi - TListView 中的边框颜色 (Delphi)

delphi - 如何更改 TTNTListView 中列中的文本颜色?

delphi - 帮助在 Delphi 2007.Net 中使用 Rijndael 算法

delphi - 我的自定义组件应该从 TDataModule 继承吗?

delphi - 从 Delphi XE 连接 TFS 2010

delphi - 如何检测 TListView 中复选框的点击