Board index » delphi » put a backround for a list view

put a backround for a list view


2006-04-16 06:30:59 PM
delphi20
I need to put an image as a background for a list view.
I used canvas bus it does not work.I need to have a background while the user is dragging and moving the icons over it.
thank you in advance.
 
 

Re:put a backround for a list view

In article <44421ce3$XXXX@XXXXX.COM>, Pooyan Zarif writes:
Quote

I need to put an image as a background for a list view.
I used canvas bus it does not work.I need to have a background
while the user is dragging and moving the icons over it.
You can process the WM_ERASEBKGND message in the listview. This is best done
using a new class derived from TListview. This example demonstrates the
principle. Tested with D2006/Win32 on Win2K.
type
TListview = class(ComCtrls.TListview)
protected
procedure WMEraseBkGnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
end;
TMainform = class(TForm)
StatusBar: TStatusBar;
ListView1: TListView;
ImageList1: TImageList;
private
FBackground: TBitmap;
protected
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
procedure ListView1DragDrop(Sender, Source: TObject; X, Y: Integer);
procedure ListView1DragOver(Sender, Source: TObject; X, Y: Integer; State:
TDragState; var Accept: Boolean);
end;
var
Mainform: TMainform;
implementation
uses Jpeg;
{$R *.dfm}
constructor TMainform.Create(AOwner: TComponent);
var
JpegImage: TJpegImage;
begin
inherited;
JpegImage := TJpegImage.Create();
try
FBackground := TBitmap.Create();
JpegImage.LoadFromFile('C:\Daten\pix\fraktal_3.jpg');
FBackground.Width := Listview1.ClientWidth;
FBackground.Height := Listview1.ClientHeight;
FBackground.Canvas.Draw(0,0, JpegImage);
finally
JpegImage.Free;
end;
end;
procedure TMainForm.ListView1DragOver(Sender, Source: TObject; X, Y:
Integer;
State: TDragState; var Accept: Boolean);
begin
accept := sender = source;
end;
procedure TMainForm.ListView1DragDrop(Sender, Source: TObject; X, Y:
Integer);
begin
If assigned( listview1.Selected ) then
listview1.Selected.SetPosition( Point(x,y));
end;
destructor TMainform.Destroy;
begin
FreeAndNil(FBackground);
inherited Destroy;
end;
procedure TListview.WMEraseBkGnd(var Message: TWMEraseBkgnd);
var
bmp: TBitmap;
CV: TCanvas;
begin
bmp := (Owner as TMainform).FBackground;
if Assigned(bmp) then begin
CV:= TCanvas.Create;
try
CV.Handle := Message.DC;
CV.Draw(0,0,bmp);
CV.Handle := 0;
finally
Message.Result := 1;
CV.Free;
end;
end
else
inherited;
end;
Peter Below (TeamB)
Don't be a vampire (slash7.com/pages/vampires),
use the newsgroup archives :
www.tamaracka.com/search.htm
groups.google.com
www.prolix.be
 

Re:put a backround for a list view

Hello Peter,
I tried this and it works, however, at least in report style,
the list view item and sub items texts are painted
non-transparant on top of the image.
Actually , not only the text, but the entire row.
This looks bad. Is there a way to suppress this?
I tried handling OnDrawItem etc. and setting Brush.Style := bsClear
but that did not help very much.
Gerrit Beuze
ModelMaker Tools
Quote
You can process the WM_ERASEBKGND message in the listview. This is best done
 

Re:put a backround for a list view

In article <XXXX@XXXXX.COM>, Gerrit Beuze writes:
Quote
I tried this and it works, however, at least in report style,
the list view item and sub items texts are painted
non-transparant on top of the image.
Actually , not only the text, but the entire row.
This looks bad. Is there a way to suppress this?
I tested it only in vsIcon mode, since that was what the OP seemed to require. I
also noticed that the icons were not drawn transparently. The only way to get
around that would be to custom draw everything. With report-style listviews that
is of course a lot more work than with vsIcon listviews.
For the latter this handler for OnCustomDrawItem seems to get reasonable
results:
procedure TMainform.ListView1CustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
var
R: TRect;
LV: TListview;
S: string;
dc: HDC;
ds: TDrawingStyle;
begin
DefaultDraw := false;
LV := Sender as TListview;
R:= Item.DisplayRect(drIcon);
if cdsFocused in State then
ds := dsFocus
else if cdsSelected in State then
ds:= dsSelected
else
ds := dsTransparent;
LV.LargeImages.Draw(LV.Canvas,
R.Left + ((R.Right-R.Left) - LV.Largeimages.Width) div 2,
R.Top, Item.ImageIndex,
ds, itImage);
if ds = dsFocus then begin
LV.Canvas.Brush.Color := clRed; // needs to be adjusted for background!
LV.Canvas.FrameRect(R);
end;
R:= Item.DisplayRect(drLabel);
S := Item.Caption;
dc:= LV.Canvas.Handle;
SetBkMode(dc, TRANSPARENT);
SetTextColor(dc, ColorToRGB(clWhite)); // needs to be adjusted for background
DrawText(dc, Pchar(S), Length(S), R,
DT_WORDBREAK or DT_CENTER or DT_NOPREFIX or DT_NOCLIP);
end;
Drawing the text transparently on a bitmap is a bit problematic since its hard
to find a suitable text color that remains readably. I'd probably opt for
drawing the text part on a solid filled background instead to work around that
problem.
Peter Below (TeamB)
Don't be a vampire (slash7.com/pages/vampires),
use the newsgroup archives :
www.tamaracka.com/search.htm
groups.google.com
www.prolix.be
 

Re:put a backround for a list view

Quote
The only way to get
around that would be to custom draw everything.
That's what I suspected.
Thanks,
Gerrit Beuze
ModelMaker Tools