September 1998

Horizontal scrollbars for list boxes

by Kent Reisdorph

It's not uncommon for a list box to contain text that's too long to fit the box's width. Such a list box needs a horizontal scrollbar so users can see the rest of the text. The vertical scrollbar in a list box appears automatically when the number of items in the list box exceeds the box's height. A horizontal scrollbar, however, requires some work to implement. In this article, we'll demonstrate how to add a horizontal scrollbar to a list box.

Keep on scrolling

To add a horizontal scrollbar to a list box, you'll first determine the width, in pixels, of the longest text item in the list box. Next, you'll send a Windows message to the list box telling it to add the horizontal scrollbar. Let's work through these steps.

How wide is wide?

When you create the horizontal scrollbar, you tell Windows how far to scroll. But before you can do that, you must determine the width of the widest item in the list box. VCL makes this part easy by providing the TCanvas class's TextWidth method, which gives the width, in pixels, of a text string. TextWidth calculates the value using the current font for the canvas. Here's an example:
int x = ListBox1->Canvas->
	TextWidth("Hello!");
Now it's a simple matter of checking all the items in the list box to see which is the longest. Depending on how you fill your list box, you can check the lengths as you add items or after you've added all the items. To check the items' length after adding them, you can use code like this:

 

int length = 0;
for (int i=0;i<ListBox1->Items->
	;Count;i++) {
  String text = ListBox1->Items->
	Strings[i];
  int l = ListBox1->Canvas->
	TextWidth(text);
  if (l > length) length = l;
}
If your list box contains a large number of items, this may not be the most efficient method of determining the longest item's length. However, it will suffice for most cases.

Adding the horizontal scrollbar

Now that you have the length of the longest item, you can tell Windows to add a horizontal scrollbar to the list box. You do so with the LB_SETHORIZONTALEXTENT Windows message, as follows:
SendMessage(ListBox1->Handle,
  LB_SETHORIZONTALEXTENT, length, 0);
You pass the scrollbar's horizontal extent in the wParam of the LB_SETHORIZONTALEXTENT message. If the list box's width is already wider than the value of wParam, Windows won't add the scrollbar. However, if the list box's width is reduced after you send the message, the scrollbar will appear. To test this theory, start a new project in C++Builder and drop a ListBox component on the form. Double-click on the form's background to generate an event handler for the OnCreate event, then enter the code from Listing A. When you run the program, the list box will display a horizontal scrollbar, as shown in Figure A.

Figure A: Our list box displays a horizontal scrollbar.
[ Figure A ]

Listing A: Adding a Horizontal Scrollbar

void __fastcall 
TForm1::FormCreate(TObject *Sender)
{
  // Put some items in the list box.
  ListBox1->Items->Add
	("This is a very long "
    "line that is too wide for
	 the list box.");
  ListBox1->Items->Add(
    "This is another very long 
	line that is "
    "too wide for the listbox.");
  ListBox1->Items->Add
	("A shorter line.");

  // Find the length of the longest item.
  int length = 0;
  for (int i=0;i<ListBox1->
	Items->Count;i++) {
    String text = ListBox1->Items-
	>Strings[i];
    int l = ListBox1->Canvas->
	TextWidth(text);
    if (l > length) length = l;
  }

  // Add a little for a good 
	visual effect.
  length += 10;

  // Tell Windows to create the scrollbar.
  SendMessage(ListBox1->Handle,
    LB_SETHORIZONTALEXTENT, length, 0);
}