views:

72

answers:

3

Hi,

how i can to to set background image to TListview in Delphi XE??

i want to make a application like Windows Explorer.

+5  A: 

In order to set a watermark in the listview you need to use the LVM_SETBKIMAGE message, and you need to override the TListView's default WM_ERASEBKGND message. The listview takes ownership of the bitmap handle, so you need to use TBitmap's ReleaseHandle, rather than just Handle.

If you want it aligned to the top-left, instead of the bottom right like Explorer, use LVBKIF_SOURCE_HBITMAP instead of LVBKIF_TYPE_WATERMARK for the ulFlags value.

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;

Stretched Watermark

The listview doesn't natively support stretching a bitmap across the entire background. To do so you need to do a StretchBlt in response to WM_ERASEBKGND yourself.

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;
Craig Peterson
@Craig Peterson: very thanks. I put your code's in the project, but has error and doesn't work.can you solve it, Please. (http://4shared.com/file/ImTrNd-Z/lvdemo_edited.html )
If you look at the code I posted, "Watermark" is a TBitmap field/property I added to TMyListView. You need to assign that instead of using LVM_SETBKIMAGE. LVM_SETBKIMAGE doesn't support stretching, so you can't use it. Also, it looks like setting the CS_HREDRAW/CS_VREDRAW styles in CreateParams messes up the drawing. Remove that and manually invalidate it in the ListView's OnResize event handler.
Craig Peterson
Also, in the code you posted, you have a TwpListView where you're adding the code, but your types are declared as TListView. You need to do the aliasing like I did in my first code sample, or create the TwpListView at runtime. As it is, none of the code in there is getting executed.
Craig Peterson
A: 

thank's for your reply.

I search in internet and found this source code. (download: http://www.4shared.com/file/vAJLseJ-/lvdemo.html )

in this source code, we set wallpaper for TListview.But this wallpaper can't to stretch when resize Form1 window(see "scr.JPG" in RAR file)

Really: Why set watermark does'nt work in this source code??

I've updated my answer with information on stretching the bitmap across the entire background. If you have any more comments you should use the "add comment" option rather than "Add another answer" so I get notified. Hope that helps.
Craig Peterson
+1  A: 

a Tlistview is nice but if you want more. i suggess you have to update with VirtualStringTree(VirtualTreeView) very flexible you can customize it almost anything you want and most of all its free.

XBasic3000