Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
Member Area
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Become a Member
-Why sign up!
-Chat Online!
-Indexes NEW!!
-Build your resume
-Find a job
-Post a job
-Resume Search
-Link to us
Visit Embarcadero
Embarcadero Community
The New Virtual List Box in Delphi 6 Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
Delphi 6.x
User Rating
No Votes
# Votes
DSP, Administrator
Reference URL:
			 Author: Alec Bergamini

What are the new virtual styles in the TListbox for, and whay are they important?


One of the new features in Delphi 6 is the addition of styles lbVirtual and 
lbVirtualOwnerDraw to the standard TListBox. In all the Delphi 6 “What’s new” 
articles I’ve read this addition has received no more than a passing mention. 

Why are Virtual List boxes important? 

Have you ever been frustrated by the limitations of the TStrings' objects property 
or have had a need to create a custom display string in the list. Sure, you can 
assign any pointer you want to the object field of a string list but what if you 
already have a list container (like a Tlist) full of data. Why should you be forced 
to duplicate this data over to the TStrings associated with the TListBox. You 
should be able to just use it. Well, with a virtual list box you can. 

During the past week I ran into a situation where I had a TInterfaceList and wanted 
to use the value returned from one of the Interface's functions as the text of the 
list item. Under Delphi 5 this required that I step down through the TInterfaceList 
calling the required interface method at each step to add the strings to the 
TListBox. Then I would need to synchronize any movement and selection in the list 
box with the TInterfaceList. Under Delphi 6, using a virtual list box, I was able 
merge my TInterfaceList and the TListbox into one highly usable pseudo object. That 
is, I was able to make the TListBox “aware” of the TInterfaceList directly. 

(BTW, my original thought was to not use the TInterfaceList at all and just place 
the references to the Interface into the object field of the TStrings member of the 
list box.. As you all probably know, this was a bad idea since it totally screws 
the reference counting on the interface.) 

Anyway I will not go into great detail about setting up a virtual list box since 
the Delphi help is pretty good on this. Basically you need to set the style to one 
of the 2 virtual styles, set the list box’s count to the number of items in the 
list and then fill in at few as one and as many as 3 events. 

Here is a trivial sample that may help to fill in some blanks left by the lack of 
sample code in the help file. 

I only wish that Borland could have also added this feature the other list controls 
like the comboboxes and the treeview. 

1   unit Unit1;
3   interface
5   uses
6     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7     Dialogs, StdCtrls;
9   type
10    TForm1 = class(TForm)
11      ListBox1: TListBox;
12      Button1: TButton;
13      Edit1: TEdit;
14      lblColor: TLabel;
15      lblNumber: TLabel;
16      procedure FormCreate(Sender: TObject);
17      procedure FormDestroy(Sender: TObject);
18      procedure ListBox1Data(Control: TWinControl; Index: Integer;
19        var Data: string);
20      function ListBox1DataFind(Control: TWinControl;
21        FindString: string): Integer;
22      procedure ListBox1DataObject(Control: TWinControl; Index: Integer;
23        var DataObject: TObject);
24      procedure Button1Click(Sender: TObject);
25      procedure ListBox1Click(Sender: TObject);
26    private
27      { Private declarations }
28    public
29      { Public declarations }
30      ObjList: TList;
31    end;
33    TMyObj = class
34      fColor: string;
35      fNumber: Integer;
36      constructor create(const color: string; const Number: Integer);
37    end;
39  var
40    Form1: TForm1;
42  implementation
44  {$R *.dfm}
46  { TMyObj }
48  constructor TMyObj.create(const color: string; const Number: Integer);
49  begin
50    fColor := color;
51    fNumber := number;
52  end;
54  { TForm1 }
56  procedure TForm1.FormCreate(Sender: TObject);
57  begin
58    // create a TList and add some data to it.
59    ObjList := TList.Create;
60    ObjList.Add(TMyObj.Create('Red', 1));
61    ObjList.Add(TMyObj.Create('Yellow', 15));
62    ObjList.Add(TMyObj.Create('Blue', 21));
63    ObjList.Add(TMyObj.Create('Green', 37));
64    ObjList.Add(TMyObj.Create('Brown', 16));
65    ObjList.Add(TMyObj.Create('Black', 5135));
66    ObjList.Add(TMyObj.Create('White', 4));
67    ObjList.Add(TMyObj.Create('Orange', 333));
68    // ABSOLUTELY REQUIRED Set the count of the virtual listbox
69    Listbox1.Count := ObjList.Count;
70  end;
72  procedure TForm1.FormDestroy(Sender: TObject);
73  var
74    I: Integer;
75  begin
76    for I := 0 to ObjList.count - 1 do
77      TMyObj(ObjList.Items[I]).free;
78    ObjList.Free;
79  end;
81  procedure TForm1.ListBox1Data(Control: TWinControl; Index: Integer;
82    var Data: string);
84  // return a string to put in the list box
85  begin
86    Data := TMyObj(ObjList.Items[Index]).fColor;
87  end;
89  procedure TForm1.ListBox1DataObject(Control: TWinControl; Index: Integer;
90    var DataObject: TObject);
92  // return an object associated with the current selection of the list box
93  begin
94    DataObject := ObjList.Items[Index];
95  end;
97  function TForm1.ListBox1DataFind(Control: TWinControl;
98    FindString: string): Integer;
100 // given a string FindString, return its index
101 var
102   I: Integer;
103 begin
104   // the simplest but most brain dead approach
105   result := -1;
106   for I := 0 to TListBox(Control).Count - 1 do
107     if TListBox(Control).Items[I] = FindString then
108       result := I;
109 end;
111 procedure TForm1.Button1Click(Sender: TObject);
112 begin
113   ListBox1.ItemIndex := ListBox1.Items.IndexOf(edit1.Text);
114   // I don't think this next should be necessary but..
115   ListBox1Click(Self);
116 end;
118 procedure TForm1.ListBox1Click(Sender: TObject);
119 begin
120   lblColor.Caption := TMyObj(ListBox1.Items.objects[Listbox1.ItemIndex]).fColor;
121   lblNumber.Caption :=
122     IntToStr(TMyObj(ListBox1.Items.objects[Listbox1.ItemIndex]).fNumber);
123 end;
125 end.

Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10


Share this page
Download from Google

Copyright © Mendozi Enterprises LLC