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
How to use Incremental Searches with a TListbox 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 2.x
User Rating
No Votes
# Votes
DSP, Administrator
Reference URL:
			Author: Lou Adler

How can I create a form that has a list box that I can perform an incremental 
search on?


There are a couple of ways to do this. One's hard and slow, the other easy and fast 
(we're going to take the easy and fast option).

For those of you who aren't familiar with incremental searching with list boxes, 
the concept is simple: A user types part of a string into an edit box, then the 
list box automatically selects one of its items that most closely matches the value 
typed by the user. For example of this, open up any topic search dialog in a 
Windows Help file. If you type into the edit box, the list will scroll to the value 
that most closely matches what you type.

Why is creating a capability like this essential? Because it's tedious to scroll 
through a list that has lots of items. Imagine if a list contained hundreds of 
unsorted items. To get to the value you're looking for would take a long time if 
you only had the capability of scrolling through the list using the vertical scroll 
bar. But if you knew at least part of the value you're trying to find, entering it 
into an edit box and getting the item you want immediately is a much more 
attractive solution.

Let's delve into what you have to do make this work. First, here's the unit code 
for a sample form I produced:

1   unit uinclist;
3   interface
5   uses
6     Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
7     StdCtrls;
9   type
10    TForm1 = class(TForm)
11      ListBox1: TListBox;
12      Edit1: TEdit;
13      procedure FormCreate(Sender: TObject);
14      procedure Edit1Change(Sender: TObject);
15    private
16      { Private declarations }
17    public
18      { Public declarations }
19    end;
21  var
22    Form1: TForm1;
24  implementation
26  {$R *.DFM}
28  procedure TForm1.FormCreate(Sender: TObject);
29  {This is a test string to load into the list box at runtime}
30  const
31    ListStrings = 'United States'#13'Guatemala'#13'Mexico'#13 +
32      'El Salvador'#13'Costa Rica'#13'Yucatan'#13 +
33      'China'#13'Japan'#13'Thailand'#13'Switzerland'#13 +
34      'Germany'#13'Lichtenstein'#13'Jamaica'#13'Greece' +
35      'Turkey'#13'Ireland'#13'United Kingdom'#13'Scotland' +
36      'Canada'#13'Uruguay'#13'Paraguay'#13'Cuba'#13 +
37      'Spain'#13'Italy'#13'France'#13'Portugal'#13'New Zealand'#13 +
38      'Austria'#13'Australia'#13'Philippines'#13'Korea'#13 +
39      'Malaysia'#13'Tibet'#13'Nepal'#13'India'#13'Sri Lanka'#13 +
40      'Pakistan'#13 + 'Saudi Arabia'#13'United Arab Emerates'#13'Iran'#13 +
41      'Ukraine'#13'Belarus'#13 +
42      'Chechen'#13'Yugoslavia'#13'Czechoslovakia'#13'Slovina'#13'Kazakhstan'#13 +
43      'Egypt'#13'Morocco'#13'Macedonia'#13'Cyprus'#13'Finland'#13 +
44      'Norway'#13'Sweden'#13'Denmark'#13'Netherlands'#13'Lithuania'#13;
45  begin
46    ListBox1.Items.SetText(ListStrings);
47  end;
49  procedure TForm1.Edit1Change(Sender: TObject);
50  var
51    S: array[0..255] of Char;
52  begin
53    StrPCopy(S, Edit1.Text);
54    with ListBox1 do
55      ItemIndex := Perform(LB_SELECTSTRING, 0, LongInt(@S));
56  end;
58  end.

Form1 has two controls: a TEdit and a TListBox. Notice that during FormCreate, I 
loaded up the value of the list box with the huge string of countries. This was 
only for testing purposes. How you load up your list is up to you. Now, the trick 
to making the incremental search is in the OnChange event of Edit1. I've used the 
Windows message LB_SELECTSTRING to perform the string selection for me. Let's talk 
about the message.

LB_SELECTSTRING is one of the members of the WinAPI list box message family (all 
preceeded by LB_) that manipulates all aspects of a list box object in Windows. The 
message takes two parameters: wParam, the index from which the search should start; 
and lParam, the address of the null-terminated string to search on. Since WinAPI 
calls require null-terminated strings, use either a PChar or an Array of Char to 
pass string values. It's more advantageous to use a an Array of Char if you know a 
string value won't exceed a certain length. You don't have to manually allocate and 
de-allocate memory with an Array of Char, as opposed to a PChar that requires you 
to use GetMem or New and FreeMem to allocate and de-allocate memory.

In any case, to convert a Pascal string to a null-terminated string, just use 
StrPCopy to copy the contents of the Pascal string into the null-terminated string. 
Once that's done, all we have to do is pass the address of the null- terminated 
string into the wParam parameter of LB_SELECTSTRING, and that's done by using the @ 

When we use Perform to execute the LB_SELECTSTRING message, the message will return 
the item index of the matching list item. Then all that's left to do is assign the 
ItemIndex property of the list box to the return value of the message. The net 
result is that the list box will scroll to and select the list element that was 

There are several list box messages you can perform in Delphi. If you bring up the 
help system and do a topic search, enter LB_ in the edit box, and peruse the list 
of messages.

Delphi Expert Eddie Shipman adds the following useful information:

This procedure can be applied to TComboBox by changing to this code:
60  procedure TForm1.ComboBox1Change(Sender: TObject);
61  var
62    S: array[0..255] of Char;
63  begin
64    StrPCopy(S, TComboBox(Sender).Text);
65    with ComboBox1 do
66      ItemIndex := Perform(CB_SELECTSTRING, 0, LongInt(@S));
67  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