2010-10-21 139 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