回答
爲了在列表視圖中設置水印,您需要使用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;
非常感謝。我把你的代碼放在項目中,但有錯誤,並且不起作用。你解決它,請。 (http://4shared.com/file/ImTrNd-Z/lvdemo_edited.html ) – User 2010-10-21 19:52:20
如果你看看我發佈的代碼,「水印」是我添加到TMyListView的TBitmap字段/屬性。您需要分配,而不是使用LVM_SETBKIMAGE。 LVM_SETBKIMAGE不支持拉伸,所以你不能使用它。另外,它看起來像在CreateParams中設置CS_HREDRAW/CS_VREDRAW樣式會使圖形出現混亂。刪除它並在ListView的OnResize事件處理程序中手動使其失效。 – 2010-10-21 20:45:15
另外,在你發佈的代碼中,你有一個TwpListView添加代碼,但是你的類型被聲明爲TListView。您需要像我在第一個代碼示例中那樣執行別名,或者在運行時創建TwpListView。事實上,沒有任何代碼正在執行。 – 2010-10-21 20:47:46
一個Tlistview是不錯,但如果你想要更多。我建議你必須更新VirtualStringTree(VirtualTreeView)非常靈活,你可以定製它幾乎任何你想要的,最重要的是它的免費。
解釋我的問題: 在我的真實項目中,我有一個TListview和一個TButton。 我想,當點擊Button1,然後設置Listview1的背景圖像(如Windows資源管理器) 請參閱圖片,在這張圖片中我設置了一個文件夾的背景圖像。 我想做一個應用程序,像這樣的圖片:http://www.4shared.com/photo/zvzwuCp_/untitled_2.html – User 2010-10-21 13:47:43