List Box Controls

Kyle Marsh
Microsoft Developer Network Technology Group

Created: March 23, 1992

Abstract

This article is a complete reference for list box controls. It describes all list box control styles, messages, and notifications in more detail than found in the MicrosoftÒ WindowsÔ version 3.x Software Development Kit (SDK) documentation.

Introduction

List box controls display a list of items from which the user can choose one or more items. List box controls can be either single column (one column of choices) or multiple column (one or more columns of choices), single selection (allowing only one item to be selected at a time) or multiple selection (allowing one or more items to be selected at a time).

Limits of List Box Controls

Several factors limit a list box control:

The control structure of a list box and its tab stop settings are allocated from the USER heap. If the USER heap does not have enough free space for these structures, the list box will not be able to operate.

In MicrosoftÒ WindowsÔ version 3.0, the control structure is 66 bytes in length; in Windows version 3.1, it's 64 bytes in length.

Windows allocates an integer to store the position of each tab stop and an integer to store the number of tab stops.

List boxes store all the strings in the list box in one globally allocated segment. Windows limits the total amount of text in a list box to 64 kilobytes (K). If the average string length in a list box is 100 bytes, for example, the list box will be able to display about 650 strings. Space for strings in a list box is allocated in multiples of 256 bytes.

Average string length
(including NULL terminator)
Maximum number of items

15 4352
30 2176
45 1450
60 1088
90 725

List boxes maintain information about each item in the list box. Storage space for this information is globally allocated, in multiples of 32 items, and limited to a total of 32K. The following information is kept for each item in a list box:

A 32-bit data value

A 16-bit index into the string storage buffer for the start of this string if the list box stores strings (that is, is not owner-drawn or has the LBS_HASSTRINGS style)

1 byte for the selected state if the list box has the LBS_MULTIPLESEL or LBS_EXTENDEDSEL styles

1 byte for the item height if the list box is a variable height owner-drawn list box (LBS_OWNERDRAWVARIABLE style)

No individual string item can be greater than 32K in length. The above values lead to the item limits in the following table.

List box attributes Maximum items Average string length to get the maximum number of items in the list box (including NULL terminator)

"Default List Box" 5440 12
LBS_EXTENDEDSEL* 4672 14
LBS_OWNERDRAWFIXED | LBS_HASSTRINGS 5440 12
LBS_OWNERDRAWFIXED |
LBS_HASSTRINGS |
LBS_EXTENDEDSEL*
4672 14
LBS_OWNERDRAWVARIABLE | LBS_HASSTRINGS 4672 14
LBS_OWNERDRAWVARIABLE | LBS_HASSTRINGS |
LBS_EXTENDEDSEL*
4064 16
LBS_OWNERDRAWFIXED 8160 N/A
LBS_OWNERDRAWFIXED | LBS_EXTENDEDSEL* 6528 N/A
LBS_OWNERDRAWVARIABLE 6528 N/A
LBS_OWNERDRAWVARIABLE | LBS_EXTENDEDSEL* 5440 N/A

* Or LBS_MULTIPLESEL

List Box Control Styles

List box controls implement the styles in the sections that follow.

LBS_NOTIFY

The LBS_NOTIFY style causes the list box to notify the list box parent window with a notification message whenever the user:

Clicks an item (LBN_SELCHANGE).

Double-clicks an item (LBN_DBLCLK).

Uses the keyboard to change a list box selection (LBN_SELCHANGE).

The list box sends these notification messages regardless of the LBS_NOTIFY setting:

LBN_ERRSPACE

LBN_SELCHANGE when the user presses CTRL+/ or CTRL+\

LBS_SORT

The LBS_SORT style causes the list box to sort strings alphabetically that are added to the list box with an LB_ADDSTRING message in either of these cases:

If the list box is not an owner-drawn list box

If the list box is an owner-drawn list box with the LBS_HASSTRINGS style

Owner-drawn list boxes without the LBS_HASSTRINGS style but with the LBS_SORT style receive WM_COMPAREITEM messages when the list box adds an item as a result of an LB_ADDSTRING message or looks for an item in the list box as a result of an LB_FINDSTRING, LB_FINDSTRINGEXACT, or LB_SELECTSTRING message.

Items added with an LB_INSERTSTRING message ignore this style.

LBS_NOREDRAW

The LBS_NOREDRAW style causes the list box to initialize the redraw status of the list box to FALSE. This, in turn, causes the list box to not update its appearance when changes to the list box are made. An application can change the redraw status of a list box by sending a WM_SETREDRAW message to the list box. (See "WM_SETREDRAW" below).

LBS_MULTIPLESEL

The LBS_MULTIPLESEL style causes the list box to allow the user to select multiple items. By default, list boxes allow only one item to be selected at a time. The LBS_MULTIPLESEL style provides a simple interface for making multiple selections. This interface does not have the power that the LBS_EXTENDEDSEL style provides for making multiple contiguous selections. If this style is combined with the LBS_EXTENDEDSEL style, the LBS_EXTENDEDSEL style overrides the LBS_MULTIPLESEL style.

This style is supplied to allow applications to create list boxes that comply with the IBM common user-access guidelines.

LBS_OWNERDRAWFIXED

The LBS_OWNERDRAWFIXED style specifies that the list box parent window is responsible for drawing, sorting, and storing the list box contents and that the items in the list box have the same height. If this style is combined with the LBS_HASSTRINGS style, the list box manages the sorting and storage of the strings in the list box. The list box sends these four messages to its parent window to inform the application of the required actions for the list box:

WM_COMPAREITEM

WM_DELETEITEM

WM_DRAWITEM

WM_MEASUREITEM

These messages are described below in the sections devoted to them.

If the LBS_OWNERDRAWFIXED style is combined with the LBS_MULTICOLUMN style, the application can set the width of the columns, as well as the height of the rows, when responding to a WM_MEASUREITEM message.

If the LBS_OWNERDRAWFIXED style is combined with the LBS_OWNERDRAWVARIABLE style, the LBS_OWNERDRAWFIXED style overrides the LBS_OWNERDRAWVARIABLE style.

LBS_OWNERDRAWVARIABLE

The LBS_OWNERDRAWVARIABLE style specifies that the items in the list box are variable in height and that the list box parent window is responsible for drawing, sorting, and storing the list box contents. The height of an item is limited to 255 pixels.

If the LBS_OWNERDRAWVARIABLE style is combined with the LBS_HASSTRINGS style, the list box manages the sorting and storage of the strings in the list box. The list box sends these four messages to its parent window to inform the application of the required actions for the list box:

WM_COMPAREITEM

WM_DELETEITEM

WM_DRAWITEM

WM_MEASUREITEM

These messages are described below in the sections devoted to them.

The list box sends a WM_MEASUREITEM message to the window that owns the list box when an item is added to the list box. The list box sends a WM_DRAWITEM message to the owner window whenever an item needs to be drawn. This can be as a result of adding or removing items from the list box or when the list box needs to be redrawn.

The LBS_OWNERDRAWVARIABLE style cannot be combined with the LBS_MULTICOLUMN style. If these two styles are combined, the LBS_OWNERDRAWVARIABLE style is ignored.

If the LBS_OWNERDRAWVARIABLE style is combined with the LBS_OWNERDRAWFIXED style, the LBS_OWNERDRAWFIXED style overrides the LBS_OWNERDRAWVARIABLE style.

The LBS_OWNERDRAWVARIABLE style causes the LBS_NOINTEGRALHEIGHT style to be enabled.

LBS_HASSTRINGS

The LBS_HASSTRINGS style specifies that the list box contains items consisting of strings. The list box maintains the memory and pointers for the strings so the application can use an LB_GETTEXT message to retrieve the text for a particular item. By default, all list boxes except owner-drawn list boxes have this style. An application can create an owner-drawn list box either with or without this style.

Owner-drawn list boxes without the LBS_HASSTRINGS style get the item's 32-bit data value in response to the LB_GETTEXT message.

LBS_USETABSTOPS

The LBS_USETABSTOPS style causes the list box to recognize and expand tab characters when drawing its strings. The default tab positions are 32 dialog box units. These tab positions can be altered using an LB_SETTABSTOPS message (see below). By default, list boxes do not expand tab characters when drawing strings.

LBS_NOINTEGRALHEIGHT

The LBS_NOINTEGRALHEIGHT style causes the list box to be exactly the size specified by the application. By default, list boxes resize themselves when created or sized so that partial items are not displayed.

For list boxes with the LBS_OWNERDRAWVARIABLE style, the LBS_NOINTEGRALHEIGHT style is always enforced.

LBS_MULTICOLUMN

The LBS_MULTICOLUMN style specifies a multiple-column list box that is scrolled horizontally. The list box control calculates a column width for itself, or an application can set the column width by sending an LB_SETCOLUMNWIDTH message to the list box. List boxes with the LBS_OWNERDRAWFIXED style can have the column set by the application when the list box sends the application a WM_MEASUREITEM message at the time it's created. By default, the column width for a list box is 15 times the average character width for the font used by the list box.

List boxes with the LBS_MULTICOLUMN style cannot be vertically scrolled. The list box ignores any WM_VSCROLL messages it receives.

The LBS_MULTICOLUMN style cannot be combined with the LBS_OWNERDRAWVARIABLE style. If these two styles are combined, the LBS_OWNERDRAWVARIABLE style is ignored.

LBS_WANTKEYBOARDINPUT

The LBS_WANTKEYBOARDINPUT style causes the list box to send WM_VKEYTOITEM or WM_CHARTOITEM messages to the list box parent window whenever the user presses a key and the list box has the input focus. This allows an application to perform special processing on the keyboard input. If a list box has the LBS_HASSTRINGS style, the list box can receive WM_VKEYTOITEM messages but not WM_CHARTOITEM messages. If a list box does not have the LBS_HASSTRINGS style, the list box can receive WM_CHARTOITEM messages as well as WM_VKEYTOITEM messages.

LBS_EXTENDEDSEL

The LBS_EXTENDEDSEL style causes the list box to allow the user to select multiple items. By default, list boxes allow only one item to be selected at a time. The LBS_EXTENDEDSEL style provides a powerful interface for making multiple contiguous selections as well as multiple noncontiguous selections. If this style is combined with the LBS_MULTIPLESEL style, the LBS_EXTENDEDSEL style overrides the LBS_MULTIPLESEL style.

LBS_DISABLENOSCROLL (Windows version 3.1 or later)

The LBS_DISABLENOSCROLL style causes the list box to disable any scroll bar that is not needed because the current contents fit the list box. Normally, when a list box scroll bar is not needed, it is hidden. The LBS_DISABLENOSCROLL style must be used in conjunction with the WS_VSCROLL or WS_HSCROLL style.

WS_VSCROLL and WS_HSCROLL

When either or both of these styles are specified for a list box, scroll bars are created for the list box.

A vertical scroll bar is displayed when there are more items in a list box without the LBS_MULTICOLUMN style than can be displayed at one time. Without a scroll style (WS_VSCROLL or WS_HSCROLL), the list box will not display a vertical scroll bar, although the list box still scrolls when the user uses the mouse or keyboard. List boxes with the LBS_MULTICOLUMN style cannot scroll vertically, so no vertical scroll bar is displayed.

A horizontal scroll bar is used by a list box on these occasions:

When the list box has the LBS_MULTICOLUMN style, and there are more items than can be displayed at one time, the list box scrolls the columns horizontally. If the list box does not have the WS_HSCROLL or WS_VSCROLL style, the user can scroll the list box horizontally only by using the keyboard. A horizontal scroll bar is required to allow the user to scroll an LBS_MULTICOLUMN list box with a mouse.

When a list box does not have the LBS_MULTICOLUMN style and the list box client window is narrower than the horizontal extent of the list box, a horizontal scroll bar is needed to scroll through the entire horizontal extent. The application must set the horizontal extent of the list box by sending the list box an LB_SETHORIZONTALEXTENT message. Without the horizontal extent set by the application, no horizontal scroll bar is displayed. See the "Considerations for Horizontal Scroll Bars in List Boxes" article on this disc for a complete discussion of horizontal scroll bars on list boxes.

LBS_STANDARD

LBS_STANDARD combines the following styles:

LBS_NOTIFY notifies the owner window of changes.

LBS_SORT sorts the items alphabetically.

WS_VSCROLL creates a vertical scroll bar in the list box.

WS_BORDER creates a border in the list box.

List Box Control Messages

List box controls implement the messages in the sections that follow.

LB_ADDSTRING

An application sends an LB_ADDSTRING message to add the string specified in the lParam parameter to a list box. If the list box has the LBS_SORT style, the string is inserted in the proper location; otherwise, it is added to the end of the list.

If the list box is owner-drawn, has the LBS_SORT style, and does not have the LBS_HASSTRINGS style, the list box sends WM_COMPAREITEM messages so the list box can sort the items correctly.

If the list box is owner-drawn and does not have the LBS_HASSTRINGS style, the item's 32-bit data value is set to the value of the lParam parameter.

LB_DELETESTRING

An application sends an LB_DELETESTRING message to a list box to remove from the list box a string or data item specified in the wParam parameter. If the list box is owner-drawn and does not have the LBS_HASSTRINGS style, the list box sends a WM_DELETEITEM message to its parent window so any storage space used for the item can be freed.

LB_DIR

An application sends an LB_DIR message to add a list of filenames to a list box, and may send this message multiple times to add different types of files or drives to the list box. The wParam parameter specifies the attributes of the files to be added to the list; the lParam parameter points to a string that contains the filename, including wildcards, to add to the list.

The valid file attributes for wParam are listed in the following table.

Value Meaning

DDL_READWRITE File can be read from or written to. This is the default value.
DDL_READONLY File can be read from but not written to.
DDL_HIDDEN File is hidden and does not appear in a directory listing.
DDL_SYSTEM File is a system file.
DDL_DIRECTORY Directories in the directory indicated by the lParam parameter.
DDL_ARCHIVE File has been archived.
DDL_DRIVES All drives that match the name specified by the lParam parameter are included. If the DDL_DRIVES flag is set, the DDL_EXCLUSIVE flag is set automatically. Therefore, to create a directory listing that includes drives and files, the application must send this message twice: once with the DDL_DRIVES flag set and once with the flags for the rest of the list.
DDL_EXCLUSIVE Exclusive flag. If the exclusive flag is set, only files of the specified type are listed. Otherwise, files of the specified type are listed in addition to files that match the default type (DLL_READWRITE).

LB_FINDSTRING

An application sends an LB_FINDSTRING message to search a list box for an item that begins with the characters specified in the lParam parameter.

The wParam parameter specifies the zero-based index of the item before the first item to be searched. When the search reaches the bottom of the list box, it continues from the top of the list box back to the item specified by the wParam parameter. If wParam is –1, the entire list box is searched from the beginning.

The lParam parameter specifies a pointer to a null-terminated string that contains the prefix to search for. The search is not case sensitive, so this string can contain any combination of uppercase and lowercase letters.

If the list box is owner-drawn and has the LBS_SORT style but does not have the LBS_HASSTRINGS style, the list box sends WM_COMPAREITEM messages to the application. If the owner-drawn list box does not have the LBS_HASSTRINGS style and also does not have the LBS_SORT style, the list box searches for an item with a 32-bit data value that matches the value of the lParam parameter.

LB_FINDSTRINGEXACT (Windows version 3.1 or later)

An application sends an LB_FINDSTRINGEXACT message to a list box to search it for an item that matches the characters specified in the lParam parameter.

The wParam parameter specifies the zero-based index of the item before the first item to be searched. When the search reaches the bottom of the list box, it continues from the top of the list box back to the item specified by the wParam parameter. If wParam is –1, the entire list box is searched from the beginning.

The lParam parameter specifies a pointer to a null-terminated string that contains the prefix to search for. The search is not case sensitive, so this string can contain any combination of uppercase and lowercase letters.

If the list box is owner-drawn and has the LBS_SORT style but does not have the LBS_HASSTRINGS style, the list box sends WM_COMPAREITEM messages to the application. If the owner-drawn list box does not have the LBS_HASSTRINGS style and also does not have the LBS_SORT style, the list box searches for an item with a 32-bit data value that matches the value of the lParam parameter. In this case, there is no functional difference between an LB_FINDSTRING message and an LB_FINDSTRINGEXACT message.

LB_GETCARETINDEX

An application sends an LB_GETCARETINDEX message to a list box to determine the index of the item that has the focus rectangle in a multiple-selection list box. The item may or may not be selected.

This message can also be used to get the index of the item that is currently selected in a single-selection list box.

LB_GETCOUNT

An application sends an LB_GETCOUNT message to a list box to get the number of items in the list box.

LB_GETCURSEL (Single-selection list boxes only)

An application sends an LB_GETCURSEL message to a list box to get the index of the currently selected item, if there is one, in a single-selection list box. If this message is sent to a multiple-selection list box, the list box returns LB_ERR.

LB_GETHORIZONTALEXTENT

An application sends an LB_GETHORIZONTALEXTENT message to a list box to get its horizontal extent. The horizontal extent is the horizontal scrolling range of the list box. By default, the horizontal extent is zero.

If the list box is a multiple-column list box, the return value is not meaningful.

LB_GETITEMDATA

An application sends an LB_GETITEMDATA message to a list box to get the 32-bit data value the list box has stored for the item specified in the wParam parameter. By default this is zero. An application must set the item data value by sending an LB_SETITEMDATA message to the list box for this value to have meaning. If the list box is an owner-drawn list box without the LBS_HASSTRINGS style, the LB_ADDSTRING or LB_INSERTSTRING message sets the 32-bit data value, and an LB_SETITEMDATA message is not required.

LB_GETITEMHEIGHT (Windows version 3.1 or later)

An application sends an LB_GETITEMHEIGHT message to a list box to get the height in pixels of an item specified in the wParam parameter. For list boxes without the LBS_OWNERDRAWVARIABLE style, the wParam item number is ignored because all items are the same height.

LB_GETITEMRECT

An application sends an LB_GETITEMRECT message to a list box to retrieve the dimensions of the rectangle that bounds an item as it is currently displayed in the list box window. The item is specified in the wParam parameter, and a pointer to a RECT structure is given in the lParam parameter.

LB_GETSEL

An application sends an LB_GETSEL message to a list box to get the selected state for an item specified in the wParam parameter. A positive return value signifies that the item is selected; a zero return value signifies that the item is not selected.

LB_GETSELCOUNT (Multiple-selection list boxes only)

An application sends an LB_GETSELCOUNT message to a list box to get the number of selected items in a multiple-selection list box. If this message is sent to a single-selection list box, LB_ERR is returned.

LB_GETSELITEMS (Multiple-selection list boxes only)

An application sends an LB_GETSELITEMS message to a list box to fill a buffer with an array of integers that specify the item numbers of selected items in a multiple-selection list box. If this message is sent to a single-selection list box, LB_ERR is returned.

The wParam parameter specifies the maximum number of selected items whose item numbers are to be placed in the buffer.

The lParam parameter specifies a long pointer to a buffer large enough for the number of integers specified by the wParam parameter.

LB_GETTEXT

An application sends an LB_GETTEXT message to a list box to retrieve a string from it.

The wParam parameter specifies the zero-based index of the string to retrieve.

The lParam parameter points to the buffer that receives the string. The buffer must have sufficient space for the string and a terminating null character. An LB_GETTEXTLEN message can be sent before an LB_GETTEXT message to retrieve the length, in bytes, of the string.

If the list box is an owner-drawn list box without the LBS_HASSTRINGS style, the buffer pointed to by the lParam parameter receives the 32-bit value associated with the item.

LB_GETTEXTLEN

An application sends an LB_GETTEXTLEN message to a list box to get the length of a string specified in the wParam parameter. The length returned does not include the NULL terminator. Owner-drawn list boxes without the LBS_HASSTRINGS style always return the size of a DWORD in response to this message.

LB_GETTOPINDEX

An application sends an LB_GETTOPINDEX message to get the index to the first visible item in the list box. Initially, the first visible item is item 0, but this changes as the list box is scrolled. For multiple-column list boxes, the first visible item is the top-left item.

LB_INSERTSTRING

An application sends an LB_INSERTSTRING message to insert an item into a list box. The inserted item is placed at the position specified by the wParam parameter. When an application uses this message, no sorting of items occurs for list boxes with the LBS_SORT style.

LB_RESETCONTENT

An application sends an LB_RESETCONTENT message to remove the contents of a list box. If the list box is an owner-drawn list box without the LBS_HASSTRINGS style, the list box sends a WM_DELETEITEM message to the list box parent window for each item it deletes from the list box.

LB_SELECTSTRING

An application sends an LB_SELECTSTRING message to search a list box for an item that begins with the characters specified in the lParam parameter and to select the item if one is found.

The wParam parameter specifies the zero-based index of the item before the first item to be searched. When the search reaches the bottom of the list box, it continues from the top of the list box back to the item specified by the wParam parameter. If wParam is –1, the entire list box is searched from the beginning.

The lParam parameter specifies a pointer to a null-terminated string that contains the prefix to search for. The search is not case sensitive, so this string can contain any combination of uppercase and lowercase letters.

If the list box is an owner-drawn list box and has the LBS_SORT style but does not have the LBS_HASSTRINGS style, the list box sends WM_COMPAREITEM messages to the parent window of the list box. If the owner-drawn list box does not have the LBS_HASSTRINGS style and also does not have the LBS_SORT style, the list box searches for an item with a 32-bit data value that matches the value of the lParam parameter.

LB_SELITEMRANGE (Multiple-selection list boxes only)

An application sends an LB_SELITEMRANGE message to select one or more consecutive items in a multiple-selection list box. If this message is sent to a single-selection list box, the list box returns LB_ERR.

LB_SETCARETINDEX

An application sends an LB_SETCARETINDEX message to set the focus rectangle to the item at the specified index in a multiple-selection list box. If this message is sent to a single-selection list box, the list box returns LB_ERR unless there is no selected item. If no item is selected, the caret index is successfully set.

The lParam parameter specifies whether the item should be scrolled into view if it is not visible. If lParam is not zero, the item will not be scrolled into view. This behavior was present but not documented for Windows version 3.0; it is documented for Windows version 3.1 and later.

LB_SETCOLUMNWIDTH

An application sends an LB_SETCOLUMNWIDTH message to set the column width for a multiple-column list box. The width in pixels is specified in the wParam parameter. All columns have the same width.

LB_SETCURSEL (Single-selection list boxes only)

An application sends an LB_SETCURSEL message to a list box to select an item and scroll it into view, if necessary. When the new item is selected, the list box removes the highlight from the previously selected item.

LB_SETCURSEL should be used only with single-selection list boxes. If this message is sent to a multiple-selection list box, the list box returns LB_ERR.

LB_SETHORIZONTALEXTENT

An application sends an LB_SETHORIZONTALEXTENT message to a list box to set its horizontal extent. The horizontal extent is the horizontal scrolling range of the list box. By default, the horizontal extent is zero. An application specifies the new horizontal extent in the wParam parameter. If the size of the list box is smaller than this value, the horizontal scroll bar is displayed to allow horizontal scrolling in the list box. If the size of the list box is equal to or greater than this value, the horizontal scroll bar is hidden. An application must create the list box with either the WS_HSCROLL or WS_VSCROLL style for the list box to support a horizontal scroll bar.

This message has no effect on multiple-column list boxes.

LB_SETITEMDATA

An application sends an LB_SETITEMDATA message to associate a 32-bit data value specified in the lParam parameter with an item in the list box that is specified in the wParam parameter.

LB_SETITEMHEIGHT (Windows version 3.1 or later)

An application sends an LB_SETITEMHEIGHT message to set the height of an item or all the items in a list box. If the list box has the LBS_OWNERDRAWVARIABLE style, this message sets the height of the item specified by the wParam parameter. Otherwise, this message sets the height of all items in the list box. The new height is specified in pixels (up to a maximum height of 255) in the low-order word of the lParam parameter.

LB_SETSEL

An application sends an LB_SETSEL message to select an item in a multiple-selection list box and scroll it into view if necessary. The wParam parameter specifies whether to select the item or cancel the selection. A TRUE value for wParam specifies that the item is selected and highlighted. A FALSE value for wParam specifies that the item is no longer selected, and the highlight is removed.

The low-order word of the lParam parameter specifies the item the selection is added to or removed from. If this value is –1, all items in the list box are selected or not, depending on the value of the wParam parameter. No scrolling occurs.

If this message is sent to a single-selection list box, the list box returns LB_ERR.

LB_SETTABSTOPS

An application sends an LB_SETTABSTOPS message to set the tab stop positions in a list box. The list box must be created with the LBS_USETABSTOPS style in order to use tab stops.

An application specifies the number of tab stops contained in the wParam parameter. If this parameter is 0, the lParam parameter is ignored, and default tab stops are set at every 32 dialog box units. If the wParam parameter is 1, tab stops are set at every n dialog box units, where n is the distance pointed to by the lParam parameter. If this parameter is greater than 1, lParam points to an array of tab stops, in dialog units.

The lParam parameter is a far pointer to an array of unsigned integers specifying the tab stops. If the wParam parameter is 1, lParam points to an unsigned integer containing the distance between all tab stops, in dialog units.

An LB_SETTABSTOPS message automatically redraws the list box.

The example below sends an LB_SETTABSTOPS message to set tab stops at every 64 dialog box units:

WORD wTabSpacing = 64;

SendDlgItemMessage(hdlg, ID_MYLISTBOX, LB_SETTABSTOPS, 1,

(DWORD) (LPWORD) &wTabSpacing);

In Windows version 3.0, edit controls calculate tab stop positions on the size of the default system font. This can cause incompatibilities between tab stops set for edit controls and those set for list boxes, which base tab stop calculations on the size of the font used in the list box. When an array of tab stop positions is used to set the tab stops for an edit control and a list box in Windows version 3.0, the tab positions may not line up the same on both the edit control and the list box. Windows version 3.1 calculates the tab stop positions using the control's font in both list boxes and edit controls.

LB_SETTOPINDEX

An application sends an LB_SETTOPINDEX message to a list box to ensure that a particular item in it is visible. The item is specified in the wParam parameter. The list box scrolls so that either the specified item appears at the top of the list box or the maximum scroll range has been reached.

WM_SETREDRAW

An application sends a WM_SETREDRAW message to a list box to reduce the amount of redrawing that it does. Keeping redrawing to a minimum improves the appearance of the list box to the user. By default, a list box redraws itself after each addition or deletion from a list box as well as at other times, such as after LB_RESETCONTENT or LB_SETCARETINDEX messages.

Note:

When a list box redraws itself as a result of receiving a WM_SETREDRAW message with the wParam parameter set to TRUE, the redraw erases the background, which in turn causes flicker. This flicker is unavoidable.

To minimize the amount of redrawing an application does, use the following steps:

1.Send a WM_SETREDRAW message to the list box with the wParam parameter set to FALSE. This clears the redraw flag for the list box.

2.Perform the actions on the list.

3.Send a WM_SETREDRAW message to the list box with the wParam parameter set to TRUE. This sets the redraw flag for the list box.

4.Call InvalidateRect with the fErase flag set to TRUE to cause the list box to redraw itself. The fErase flag ensures that the list box will have the correct appearance.

The example below adds nItems to a list box:

SendMessage(hwndListBox, WM_SETREDRAW, FALSE, 0L);

for ( i = 0; i < nItems; i++ )

SendMessage(hwndListBox, LB_ADDSTRING, 0, lpStrings[i]);

SendMessage(hwndListBox, WM_SETREDRAW, TRUE, 0L);

InvalidateRect(hwndListBox, NULL, TRUE);

Notification Messages

The parent window of a list box receives notification messages through WM_COMMAND messages.

The wParam parameter specifies the identifier of the list box, and the lParam parameter specifies the handle to the list box in the low-order word and the notification code in the high-order word.

LBN_DBLCLK

A list box created with the LBS_NOTIFY style sends an LBN_DBLCLK notification message to its parent window when the user double-clicks a string in it.

LBN_ERRSPACE

A list box sends an LBN_ERRSPACE notification message to its parent window when it cannot allocate enough memory to complete the current operation. This can occur when adding an item to a list box. A list box does not need the LBS_NOTIFY style to receive this notification.

LBN_KILLFOCUS

A list box sends an LBN_KILLFOCUS notification message to its parent window when the list box loses the input focus. This message is sent when the list box receives a WM_KILLFOCUS message from Windows.

LBN_SELCANCEL

A list box created with the LBS_NOTIFY style sends an LBN_SELCANCEL notification message to its parent window when the user cancels the selection in the list box.

LBN_SELCHANGE

A list box created with the LBS_NOTIFY style sends an LBN_SELCHANGE notification message to its parent window when the selection is about to change due to mouse or keyboard user input. This message is not sent if LB_SETCURSEL, LB_SELECTSTRING, LB_SETSEL, or LB_SELECTITEMRANGE messages are sent from the application. LBN_SELCHANGE is always sent to the application, regardless of the LBS_NOTIFY style, when the user presses CTRL+/ or CTRL+\.

LBN_SETFOCUS

A list box sends an LBN_SETFOCUS notification message to its parent window when the list box gains the input focus. This message is sent when the list box receives a WM_SETFOCUS message from Windows.

Selection Messages

A list box control sends the following messages to its owner window when the list box has the LBS_WANTKEYBOARDINPUT style.

WM_CHARTOITEM

An owner-drawn list box that does not have the LBS_HASSTRINGS style sends a WM_CHARTOITEM message to its parent window when the list box receives a WM_CHAR message. The wParam parameter contains the value of the key the user pressed. The low-order word of the lParam parameter contains the list box window handle, and the high-order word of lParam contains the current caret position.

The application specifies the action the list box should take in the value it returns to the list box. A return value of:

–2 indicates that the application handled all aspects of selecting the item and requires no further action by the list box.

–1 indicates that the list box should perform the default action in response to the keystroke.

0 or greater specifies the zero-based index of an item in the list box and indicates that the list box should perform the default action for the keystroke on the given item.

WM_VKEYTOITEM

A list box that has the LBS_HASSTRINGS style sends a WM_VKEYTOITEM message to its parent window when the list box receives a WM_KEYDOWN message. The wParam parameter contains the value of the key the user pressed. The low-order word of the lParam parameter contains the list box window handle, and the high-order word of lParam contains the current caret position.

The application specifies what action the list box should take in the value it returns to the list box. A return value of:

–2 indicates that the application handled all aspects of selecting the item and requires no further action by the list box.

–1 indicates that the list box should perform the default action in response to the keystroke.

0 or greater specifies the zero-based index of an item in the list box and indicates that the list box should perform the default action for the keystroke on the given item.

Owner-drawn Messages

Windows version 3.1 changed the way the wParam parameter is used in the owner-drawn messages sent from list boxes to their parent windows. In Windows version 3.1 and later, the wParam parameter contains the list box identifier; in earlier versions of Windows, the wParam parameter contained zero.

WM_COMPAREITEM

An owner-drawn list box that has the LBS_SORT style and does not have the LBS_HASSTRINGS style sends a WM_COMPAREITEM message to its parent window when the list box receives an LB_ADDSTRING, LB_FINDSTRING, LB_FINDSTRINGEXACT, or LB_SELECTSTRING message. Usually the list box needs to send this message multiple times as it locates or adds an item. The lParam parameter contains a far pointer to a COMPAREITEMSTRUCT data structure that contains the identifiers and the 32-bit data values for two items in the list box.

The application indicates the relative position of the two items by returning a value to the list box. The valid return values are:

–1 when item 1 precedes item 2 in the sorted order.

0 when item 1 and item 2 are equivalent in the sorted order.

1 when item 1 follows item 2 in the sorted order.

WM_DELETEITEM

An owner-drawn list box sends a WM_DELETEITEM message to its parent window when an item is deleted from the list box with an LB_DELETESTRING or LB_RESETCONTENT message or when the list box is destroyed. The lParam parameter contains a far pointer to a DELETEITEMSTRUCT data structure that contains information about the item being deleted.

WM_DRAWITEM

An owner-drawn list box sends a WM_DRAWITEM message to its parent window when the list needs to update its display. The lParam parameter contains a far pointer to a DRAWITEMSTRUCT structure that contains information about the item to be drawn and the type of drawing required.

The itemAction member of the DRAWITEMSTRUCT structure defines the drawing operation that is to be performed.

Before returning from processing this message, an application should ensure that the device context identified by the hDC member of the DRAWITEMSTRUCT structure is in the default state.

This example shows how to process a WM_DRAWITEM message:

LPDRAWITEMSTRUCT lpdis;

case WM_DRAWITEM:

lpdis = (DRAWITEMSTRUCT FAR*) lParam;

switch (lpdis->itemAction) {

case ODA_DRAWENTIRE:

.

. /* Redraw the entire control or menu. */

.

return TRUE;

case ODA_SELECT:

.

. /* Redraw to reflect current selection state. */

.

return TRUE;

case ODA_FOCUS:

.

. /* Redraw to reflect current focus state. */

.

return TRUE;

}

break;

WM_MEASUREITEM

A list box that has the LBS_OWNERDRAWFIXED style sends a WM_MEASUREITEM message to its parent window when the list box is created. A list box that has the LBS_OWNERDRAWVARIABLE style sends a WM_MEASUREITEM message to its parent window each time an item is added to the list box. The lParam parameter contains a far pointer to a MEASUREITEMSTRUCT structure that contains information about the item being added.

The application fills the itemHeight field of the MEASUREITEMSTRUCT structure with the height for the item. If the list box has the LBS_MULTICOLUMN and LBS_OWNERDRAWFIXED styles, the application can also fill the itemWidth field to set the column width for the list box.