?
Solved

Tiled background image in listbox

Posted on 2002-06-17
11
Medium Priority
?
879 Views
Last Modified: 2007-11-27
Hi,

I want to create watermarks in instances of TListBox and TLMDListBox.

That is, i want to place one faint background image on the listbox and have it tiled all over the listbox. Even in case i resize my form (the listbox will also be resized), the image should get tiled smoothly, leaving no white space behind on the listbox.  

Does anyone have a clue as to how can it be done?

Thanks a lot in advance...
0
Comment
Question by:sazehra
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
  • 2
11 Comments
 
LVL 1

Expert Comment

by:alx512
ID: 7086488
Heh, very difficult task.
The simple way is to use the TListView component.
0
 

Author Comment

by:sazehra
ID: 7086741
hmmm... ok, then how do i do it using TListView?
0
 
LVL 1

Expert Comment

by:alx512
ID: 7087636
Sorry. It was a mistake. I think what TListView has a BackGroundImage property.
May be easy to create a new Component whith own draw code.
It must look like this:

On WM_ERASEBKGND :

  r := ClientRect;
  rgn := CreateRectRgnIndirect(r);
  SelectClipRgn(Canvas.Handle, rgn);
  Canvas.StretchDraw(r, FPicture.Bitmap);
  SelectClipRgn(Sender.Canvas.Handle, 0);
  DeleteObject(rgn);


On WM_DRAWITEM:

    Flags := DrawTextBiDiModeFlags(DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX);
    SetBkMode(Canvas.Handle, TRANSPARENT);
    DrawText(Canvas.Handle, PChar(Text), Length(Text), Rect, Flags);
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 34

Accepted Solution

by:
Slick812 earned 120 total points
ID: 7090679
hello sazehra, you can set the TListBox Style to lbOwnerDrawFixed. The ItemHeight is set in your FormCreate. Now go to the ListBox1 Object Inspector and get the events, and double click OnDrawItem.

private
    { Private declarations }
    LbBmp: TBitmap;

procedure TForm1.FormCreate(Sender: TObject);
var
TempBmp: TBitmap;
X,Y: Integer;
begin
TempBmp := TBitmap.Create;
{I draw the tiled Bmp (TempBmp) but you should load it from Resource}
{TempBmp.LoadFromResourceName(hInstance, 'LBBACK');}
TempBmp.Canvas.Brush.Color := $00D8E8F8;
TempBmp.Height := 42;
TempBmp.Width := 42;
TempBmp.Canvas.Brush.Color := $00CFE9F0;
TempBmp.Canvas.Pen.Color := $00B0CEDF;
TempBmp.Canvas.Ellipse(4,5,34,32);
LbBmp := TBitmap.Create;
LbBmp.Height := TempBmp.Height * 2;
{all you need is twice the TempBmp height no matter
how tall the Listbox is}
LbBmp.Width := ListBox1.Width * 2;
{set the LbBmp width to the maximum that the List box can get to
maybe LbBmp.Width := Screen.Width}
Y := 0;
{this while loop tile's the TempBmp on the LbBmp}
while Y < LbBmp.Height do
  begin
  X := 0;
  while X < LbBmp.Width do
    begin
    LbBmp.Canvas.Draw(X, Y, TempBmp);
    Inc(X, TempBmp.Width);
    end;
  Inc(Y, TempBmp.Height);
  end;
TempBmp.Canvas.Font := ListBox1.Font;
ListBox1.ItemHeight := TempBmp.Canvas.TextHeight('W')+1;
ListBox1.ClientHeight := ListBox1.ClientHeight - (ListBox1.ClientHeight mod ListBox1.ItemHeight);
{It is Important to adjust the Client Height to keep blank spots off the bottom of the Listbox}
FreeAndNil(TempBmp);
end;


procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  ARect: TRect; State: TOwnerDrawState);
var
CopyRect: TRect;
Y: Integer;
begin
{don't draw anything if out of sight}
if (ARect.Top < -3) or (ARect.Top > ListBox1.Height+2) then
Exit;
CopyRect := ARect;
if Index > 0 then
  begin
  {adjust the CopyRect to the Item Index}
  CopyRect.Top := Index * (ARect.Bottom- ARect.Top);
  if CopyRect.Top > LbBmp.Height div 2 then
  CopyRect.Top := CopyRect.Top mod (LbBmp.Height div 2);
  CopyRect.Bottom := CopyRect.Top +(ARect.Bottom- ARect.Top);
  end;

(Control as TListBox).Canvas.Font := ListBox1.Font;
Y := (ListBox1.Items.Count) * ListBox1.ItemHeight;

if Y < ListBox1.Height then
  begin
  {you need to fill out the canvas below the last item if Y is less than height}
  (Control as TListBox).Canvas.CopyRect(Rect(0,Y,ARect.Right,Y+LbBmp.Height-(Y mod (LbBmp.Height div 2))),
                  LbBmp.Canvas,Rect(0,(Y mod (LbBmp.Height div 2)),ARect.Right,LbBmp.Height));
  Y:= Y+LbBmp.Height-(Y mod (LbBmp.Height div 2));
  while Y < ListBox1.Height do
    begin
    (Control as TListBox).Canvas.Draw(0, Y, LbBmp);
    Inc(Y, LbBmp.Height);
    end;
  end;

if odSelected in State then
  begin
  {change the colors for selected}
  (Control as TListBox).Canvas.Brush.Color := clHighLight;
  (Control as TListBox).Canvas.FillRect(ARect);
  (Control as TListBox).Canvas.Font.Color := clHighLightText;
  end else
(Control as TListBox).Canvas.CopyRect(ARect,LbBmp.Canvas,CopyRect);

(Control as TListBox).Canvas.Brush.Style := bsClear;
if (odDisabled in State) or (odGrayed in State) then
(Control as TListBox).Canvas.Font.Color := clGrayText;
{change text color for disabled}
(Control as TListBox).Canvas.TextOut(ARect.Left+2,ARect.Top,ListBox1.Items[Index]);
end;


procedure TForm1.sbut_DisListBClick(Sender: TObject);
begin
ListBox1.Enabled := not ListBox1.Enabled;
end;

procedure TForm1.sbut_AddListBClick(Sender: TObject);
begin
ListBox1.Clear;
ListBox1.Items.Add('First Line');
ListBox1.Items.Add('Second Line');
ListBox1.Items.Add('Third Line');
ListBox1.Items.Add('Fourth Line');
end;


- - - - - - - - - - - - - - - - - - - - - - - - - - - -

ask questions if it is unclear.
0
 
LVL 34

Expert Comment

by:Slick812
ID: 7090688
don't forget to free the LbBmp in your form's OnDestroy
0
 

Author Comment

by:sazehra
ID: 7098389
Hello Slick812,

Thanks a lot... Your works wonderfully with TListBox.

However, there is a little problem when i use it with TLMDListBox. I have 4 columns in it. Using your code, all the items appear in 1 column with semi-colon seperated list. I'll try to depict it...

This is what i should get:

Col1     Col2     Col3     Col4
----     ----     ----     ----

Itm11    Itm12    Itm13    Itm14
Itm21    Itm22    Itm23    Itm24
Itm31    Itm32    Itm33    Itm34
.....    .....    .....    .....



and this is what i m getting:

Col1     Col2     Col3     Col4
----     ----     ----     ----

Itm11;Itm12;Itm13;Itm14
Itm21;Itm22;Itm23;Itm24
Itm31;Itm32;Itm33;Itm34
.......................

the resizing of columns do not have any effect on the items in the LMDlistbox.

i'll be very grateful if u could help in this as well.

Thanks again!

0
 

Author Comment

by:sazehra
ID: 7098400
actually i don't want to change the control if possible...
0
 
LVL 34

Expert Comment

by:Slick812
ID: 7099561
I'm not familar with the TLMDListBox component, is it a standard delphi component or an add On. You may look at the properties of the Columns, like width and when there is a single ";" in the items text then move the text draw over to the next column width to place the text at the right spot, deleting the ; so it will not show.
0
 

Author Comment

by:sazehra
ID: 7099973
No TLMDListBox isn't a standard component.

ok, i'll try what u have suggested but the columns are resizeable so i m not sure if that'll b the best way to do it. Thanks anyway...
0
 
LVL 34

Expert Comment

by:Slick812
ID: 7099991
there should be a column width property somewhere, since the columns are resizable then it may be associated with the header, which I guess is a sub component?
0
 

Author Comment

by:sazehra
ID: 7118191
Hello, Slick812,

I didn't succeed with TLMDListBox so decided to change the component. But your code works beatifully with TListBox. Thank you very much.

Regards.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
Suggested Courses
Course of the Month15 days, 10 hours left to enroll

741 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question