Borland Online And The Cobb Group Present:


February, 1996 - Vol. 3 No. 2

Owner-drawn list boxes without strings

In the article Owner-drawn list boxes in OWL we show you how to create an owner-drawn list box that contains strings. You can also store other types of data, such as pointers to a class, in a list box. Of course, to display this kind of data, you'll have to use owner drawing.

In addition to providing storage for strings in a list box, Windows also provides storage for a DWORD associated with each of the list box's items. This DWORD is called the item data, and you can use this storage space in any manner you choose. You can set the item data by using the TListBox::SetItemData() function, provided that the list box is set to the LBS_HASSTRINGS style. This way, you can store additional data along with the string.

But what if you only want to store pointers to objects and not strings at all? In that case, you won't be using the LBS_HASSTRINGS style. There is no AddItemData() function­­so how do you add the pointers? Windows provides for this situation by allowing you to pass a pointer to your object in the LB_ADDSTRING message (implemented in OWL via the TListBox::AddString() function).

When your list box doesn't use strings, Windows transfers the pointer you pass in AddString() to the item data DWORD. In order to facilitate this, you need to do a little casting. You cast your pointer to a LPCSTR in AddString() and back to a pointer of your class type in your ODADrawEntire() function.

For example, suppose you had an array of bitmaps that you wanted to display in a list box. As we mentioned, you wouldn't include the LBS_HASSTRINGS style for the list box. You'd first need to add the pointers to the list box. Assuming you had an array of TBitmap pointers called myBitmaps, the code would look like this:

void MyListBox::SetupWindow()
{
   TListBox::SetupWindow();
   for (int i=0;i<numBitmaps;i++)
      AddString((LPCSTR)myBitmaps[i]);
}

Then, when it's time to display your bitmaps (in your ODADrawEntire() function), you'd retrieve the bitmaps with the following code:

void MyListBox::ODADrawEntire(DRAWITEMSTRUCT& di)
{
   TBitmap* bitmap = (TBitmap*)di.itemData;
    // etc.
}

To be type-safe, you could use dynamic_cast to perform the cast, testing for a non-NULL pointer before using the pointer.

You should be aware of a special consideration when your list box doesn't use LBS_HASSTRINGS: If your list box is sorted (LBS_SORT), you'll need to provide the code to compare your items. You do this by overriding the TControl class's CompareItem() member function. Once you've provided this function, storing and using pointers in owner-drawn list boxes is nearly as easy as using the more conventional method of storing strings.

Return to the Borland C++ Developer's Journal index

Subscribe to the Borland C++ Developer's Journal


Copyright (c) 1996 The Cobb Group, a division of Ziff-Davis Publishing Company. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of Ziff-Davis Publishing Company is prohibited. The Cobb Group and The Cobb Group logo are trademarks of Ziff-Davis Publishing Company.