Solved

Tiled background image in listbox

Posted on 2002-06-17
11
866 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
  • 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
Are your AD admin tools letting you down?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

 
LVL 33

Accepted Solution

by:
Slick812 earned 30 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 33

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 33

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 33

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

Best Practices: Disaster Recovery Testing

Besides backup, any IT division should have a disaster recovery plan. You will find a few tips below relating to the development of such a plan and to what issues one should pay special attention in the course of backup planning.

Question has a verified solution.

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

Suggested Solutions

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…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.

809 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