2010-10-21 52 views
1

我怎么能在Delphi XE中将背景图像设置为TListview?如何在Delphi XE中将背景图像设置为TListview?

我想制作一个应用程序,如Windows资源管理器。

+0

解释我的问题: 在我的真实项目中,我有一个TListview和一个TButton。 我想,当点击Button1,然后设置Listview1的背景图像(如Windows资源管理器) 请参阅图片,在这张图片中我设置了一个文件夹的背景图像。 我想做一个应用程序,像这样的图片:http://www.4shared.com/photo/zvzwuCp_/untitled_2.html – User 2010-10-21 13:47:43

回答

7

为了在列表视图中设置水印,您需要使用LVM_SETBKIMAGE消息,并且需要重写TListView的默认WM_ERASEBKGND消息。列表视图获取位图句柄的所有权,因此您需要使用TBitmap的ReleaseHandle,而不仅仅是Handle

如果您希望它与左上角对齐,而不是像Explorer那样右下角,请使用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; 

拉伸水印

ListView中本身不支持在整个背景拉伸的位图。要做到这一点,你需要自己做一个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; 
+0

非常感谢。我把你的代码放在项目中,但有错误,并且不起作用。你解决它,请。 (http://4shared.com/file/ImTrNd-Z/lvdemo_edited.html ) – User 2010-10-21 19:52:20

+0

如果你看看我发布的代码,“水印”是我添加到TMyListView的TBitmap字段/属性。您需要分配,而不是使用LVM_SETBKIMAGE。 LVM_SETBKIMAGE不支持拉伸,所以你不能使用它。另外,它看起来像在CreateParams中设置CS_HREDRAW/CS_VREDRAW样式会使图形出现混乱。删除它并在ListView的OnResize事件处理程序中手动使其失效。 – 2010-10-21 20:45:15

+0

另外,在你发布的代码中,你有一个TwpListView添加代码,但是你的类型被声明为TListView。您需要像我在第一个代码示例中那样执行别名,或者在运行时创建TwpListView。事实上,没有任何代码正在执行。 – 2010-10-21 20:47:46

相关问题