About List Boxes

A list box control contains a simple list from which the user can generally select one or more items. List boxes provide limited flexibility compared with List View controls.

List box items can be represented by text strings, bitmaps, or both. If the list box is not large enough to display all the list box items at once, the list box provides a scroll bar. The user scrolls through the list box items and applies or removes selection status as necessary. Selecting a list box item changes its visual appearance, usually by changing the text and background colors to those specified by the relevant operating system metrics. When the user selects or deselects an item, the system sends a notification message to the parent window of the list box.

For an ANSI application, the system converts the text in a list box to Unicode by using the CP_ACP code page. This can cause problems. For example, accented Roman characters in a non-Unicode list box in Windows, Japanese version will come out garbled. To fix this, either compile the application as Unicode or use an owner-drawn list box.

This section discusses the following topics:

Creating a List Box

The easiest way to create a list box in a dialog box is to drag it from the Toolbox in Microsoft Visual Studio onto your dialog resource. To create a list box dynamically, or to create a list box in a window other than a dialog box, use the CreateWindowEx function, specifying the WC_LISTBOX window class and the appropriate list box styles.

List Box Types and Styles

There are two types of list boxes: single-selection (the default) and multiple-selection. In a single-selection list box, the user can select only one item at a time. In a multiple-selection list box, the user can select more than one item at a time. To create a multiple-selection list box, specify the LBS_MULTIPLESEL or the LBS_EXTENDEDSEL style.

The appearance and operation of a list box is controlled by list box styles and window styles. These styles indicate whether the list is sorted, arranged in multiple columns, drawn by the application, and so on. The dimensions and styles of a list box are typically defined in a dialog box template that is included in an application's resources.

Note

To use visual styles with these controls, an application must include a manifest and must call InitCommonControls at the beginning of the program. For information on visual styles, see Visual Styles. For information on manifests, see Enabling Visual Styles.

List Box Functions

The DlgDirList function replaces the contents of a list box with the names of drives, directories, and files that match a specified set of criteria. The DlgDirSelectEx function retrieves the current selection in a list box that is initialized by DlgDirList. These functions make it possible for the user to select a drive, directory, or file from a list box without typing the location and name of the file.

Also, the GetListBoxInfo function returns the number of items per column in a specified list box.

Notification Messages from List Boxes

When an event occurs in a list box, the list box sends a notification code, in the form of a WM_COMMAND message, to the dialog box procedure of the owner window. List box notification codes are sent when a user selects, double-clicks, or cancels a list box item; when the list box receives or loses the keyboard focus; and when the system cannot allocate enough memory for a list box request. A WM_COMMAND message contains the list box identifier in the low-order word of the wParam parameter, and the notification code in the high-order word. The lParam parameter contains the control window handle.

A dialog box procedure is not required to process these messages; the default window procedure processes them.

An application should monitor and process the following list box notification codes.

Notification code Description
LBN_DBLCLK The user double-clicks an item in the list box.
LBN_ERRSPACE The list box cannot allocate enough memory to fulfill a request.
LBN_KILLFOCUS The list box loses the keyboard focus.
LBN_SELCANCEL The user cancels the selection of an item in the list box.
LBN_SELCHANGE The selection in a list box is about to change.
LBN_SETFOCUS The list box receives the keyboard focus.

Messages to List Boxes

A dialog box procedure can send messages to a list box to add, delete, examine, and change list box items. For example, a dialog box procedure could send an LB_ADDSTRING message to a list box to add an item, and an LB_GETSEL message to determine whether the item is selected. Other messages set and retrieve information about the size, appearance, and behavior of the list box. For example, the LB_SETHORIZONTALEXTENT message sets the scrollable width of a list box. A dialog box procedure can send any message to a list box by using the SendMessage or SendDlgItemMessage function.

A list box item is often referenced by its index, an integer that represents the item's position in the list box. The index of the first item in a list box is 0, the index of the second item is 1, and so on.

The following table describes how the predefined list box procedure responds to list box messages.

Message Response
LB_ADDFILE Inserts a file into a directory list box that is filled by the DlgDirList function and retrieves the list box index of the inserted item.
LB_ADDSTRING Adds a string to a list box and returns its index.
LB_DELETESTRING Removes a string from a list box and returns the number of strings that remain in the list.
LB_DIR Adds a list of file names to a list box and returns the index of the last file name added.
LB_FINDSTRING Returns the index of the first string in the list box that begins with a specified string.
LB_FINDSTRINGEXACT Returns the index of the string in the list box that is equal to a specified string.
LB_GETANCHORINDEX Returns the index of the item that the mouse last selected.
LB_GETCARETINDEX Returns the index of the item that has the focus rectangle.
LB_GETCOUNT Returns the number of items in the list box.
LB_GETCURSEL Returns the index of the currently selected item.
LB_GETHORIZONTALEXTENT Returns the scrollable width, in pixels, of a list box.
LB_GETITEMDATA Returns the value that is associated with the specified item.
LB_GETITEMHEIGHT Returns the height, in pixels, of an item in a list box.
LB_GETITEMRECT Retrieves the client coordinates of the specified list box item.
LB_GETLOCALE Retrieves the locale of the list box. The high-order word contains the country/region code and the low-order word contains the language identifier.
LB_GETSEL Returns the selection state of a list box item.
LB_GETSELCOUNT Returns the number of selected items in a multiple-selection list box.
LB_GETSELITEMS Creates an array of the indexes of all selected items in a multiple-selection list box and returns the total number of selected items.
LB_GETTEXT Retrieves the string associated with a specified item and the length of the string.
LB_GETTEXTLEN Returns the length, in characters, of the string associated with a specified item.
LB_GETTOPINDEX Returns the index of the first visible item in a list box.
LB_INITSTORAGE Allocates memory for the specified number of items and their associated strings.
LB_INSERTSTRING Inserts a string at a specified index in a list box.
LB_ITEMFROMPOINT Retrieves the zero-based index of the item nearest the specified point in a list box.
LB_RESETCONTENT Removes all items from a list box.
LB_SELECTSTRING Selects the first string it finds that matches a specified prefix.
LB_SELITEMRANGE Selects a specified range of items in a list box.
LB_SELITEMRANGEEX Selects a specified range of items if the index of the first item in the range is less than the index of the last item in the range. Cancels the selection in the range if the index of the first item is greater than the last.
LB_SETANCHORINDEX Sets the item that the mouse last selected to a specified item.
LB_SETCARETINDEX Sets the focus rectangle to a specified list box item.
LB_SETCOLUMNWIDTH Sets the width, in pixels, of all columns in a list box.
LB_SETCOUNT Sets the number of items in a list box.
LB_SETCURSEL Selects a specified list box item.
LB_SETHORIZONTALEXTENT Sets the scrollable width, in pixels, of a list box.
LB_SETITEMDATA Associates a value with a list box item.
LB_SETITEMHEIGHT Sets the height, in pixels, of an item or items in a list box.
LB_SETLOCALE Sets the locale of a list box and returns the previous locale identifier.
LB_SETSEL Selects an item in a multiple-selection list box.
LB_SETTABSTOPS Sets the tab stops to those specified in a specified array.
LB_SETTOPINDEX Scrolls the list box so the specified item is at the top of the visible range.

Default Window Message Processing

The window procedure for the predefined list box window class carries out default processing for all messages that the list box does not process. When the list box procedure returns FALSE for a message, the predefined window procedure checks the message and performs default actions, as shown in the following table.

Message Default action
WM_CHAR Moves the selection to the first item that begins with the character that the user typed. If the list box has the LBS_OWNERDRAW style, no action occurs. Multiple characters that are typed within a short interval are treated as a group, and the first item that begins with that series of characters is selected.
WM_CREATE Creates an empty list box.
WM_DESTROY Destroys the list box and frees any resources that it uses.
Passes the message to the dialog box procedure or parent window process.
WM_ENABLE If the control is visible, invalidates the rectangle so the strings can be painted gray.
WM_ERASEBKGND Erases the background of a list box. If the list box has the LBS_OWNERDRAW style, the background is not erased.
WM_GETDLGCODE Returns DLGC_WANTARROWS | DLGC_WANTCHARS, indicating that the default list box procedure processes the arrow keys and WM_CHAR messages.
WM_GETFONT Returns a handle to the current font for the list box.
WM_HSCROLL Scrolls the list box horizontally.
WM_KEYDOWN Processes virtual keys for scrolling. The virtual key is the index of the item to move the caret to. The selection is not changed.
WM_KILLFOCUS Turns the caret off and destroys it. Sends an LBN_KILLFOCUS notification code to the owner of the list box.
WM_LBUTTONDBLCLK Tracks the mouse in the list box client area. This enables the user to cancel a selection if the mouse button is released outside the list box client area.
WM_LBUTTONDOWN Tracks the mouse in the list box client area. This enables the user to cancel a selection if the mouse button is released outside the list box client area.
WM_LBUTTONUP Tracks the mouse in the list box client area. This enables the user to cancel a selection if the mouse button is released outside the list box client area.
WM_MOUSEMOVE Tracks the mouse in the list box client area. This enables the user to cancel a selection if the mouse button is released outside the list box client area.
WM_PAINT Performs a subclassed paint operation by using the list box handle to the device context (DC).
WM_SETFOCUS Turns the caret on and sends an LBN_SETFOCUS notification code to the owner of the list box.
WM_SETFONT Sets a new font for the list box.
WM_SETREDRAW Sets or clears the redraw flag based on the value of wParam.
WM_SIZE Resizes the list box to an integral number of items.
WM_VSCROLL Scrolls the list box vertically.

The predefined list box procedure passes all other messages to DefWindowProc for default processing.

Owner-Drawn List Boxes

An application can create an owner-drawn list box to take responsibility for painting list items. The parent window or dialog box of an owner-drawn list box (its owner) receives WM_DRAWITEM messages when a portion of the list box needs to be painted. An owner-drawn list box can list information other than, or in addition to, text strings.

The owner of an owner-drawn list box must process the WM_DRAWITEM message. This message is sent whenever a portion of the list box must be redrawn. The owner may need to process other messages, depending on the styles specified for the list box.

An application can create an owner-drawn list box by specifying the LBS_OWNERDRAWFIXED or LBS_OWNERDRAWVARIABLE style. If all list items in the list box are the same height, such as strings or icons, an application can use the LBS_OWNERDRAWFIXED style. If list items are of varying height (for example, bitmaps of different size) an application can use the LBS_OWNERDRAWVARIABLE style.

The owner of an owner-drawn list box can process a WM_MEASUREITEM message to specify the dimensions of list items. If the application creates the list box by using the LBS_OWNERDRAWFIXED style, the system sends the WM_MEASUREITEM message only once. The dimensions that are specified by the owner are used for all list items. If the LBS_OWNERDRAWVARIABLE style is used, the system sends a WM_MEASUREITEM message for each list item that is added to the list box. The owner can determine or set the height of a list item at any time by using the LB_GETITEMHEIGHT and LB_SETITEMHEIGHT messages, respectively.

If the information displayed in an owner-drawn list box includes text, an application can keep track of the text for each list item by specifying the LBS_HASSTRINGS style. List boxes with the LBS_SORT style are sorted based on this text. If a list box is sorted, but is not of the LBS_HASSTRINGS style, the owner must process the WM_COMPAREITEM message.

In an owner-drawn list box, the owner must keep track of list items that contain information other than or in addition to text. One convenient way to do this is to save the handle to the information as item data by using the LB_SETITEMDATA message. To free data objects associated with items in a list box, the owner can process the WM_DELETEITEM message.

For an example of an owner-drawn list box, see How to Create an Owner-Drawn List Box.

Drag List Boxes

A drag list box is a special type of list box that enables the user to drag items from one position to another. An application can use a drag list box to display strings in a particular sequence and enable the user to change the sequence by dragging the items into position.

Creating Drag List Boxes

Drag list boxes have the same window styles and process the same messages as standard list boxes. To create a drag list box, first create a standard list box and then call the MakeDragList function. To convert a list box in a dialog box to a drag list box, you can call MakeDragList when the WM_INITDIALOG message is processed.

Drag List Box Messages

A drag list box notifies the parent window of drag events by sending it a drag list message. The parent window must process the drag list message.

The drag list box registers this message when the MakeDragList function is called. To retrieve the message identifier (numeric value) of the drag list message, call the RegisterWindowMessage function and specify the DRAGLISTMSGSTRING value.

The wParam parameter of the drag list message is the control identifier for the drag list box. The lParam parameter is the address of a DRAGLISTINFO structure, which contains the notification code for the drag event and other information. The return value of the message depends on the notification.

Drag List Box Notification Codes

The drag list notification code, which is identified by the uNotification member of the DRAGLISTINFO structure included with the drag list message, can be DL_BEGINDRAG, DL_DRAGGING, DL_CANCELDRAG, or DL_DROPPED.

The DL_BEGINDRAG notification code is sent when the cursor is on a list item and the user clicks the left mouse button. The parent window can return TRUE to begin the drag operation or FALSE to disallow dragging. In this way, the parent window can enable dragging for some list items and disable it for others. You can determine which list item is at the specified location by using the LBItemFromPt function.

If dragging is in effect, the DL_DRAGGING notification code is sent whenever the mouse is moved, or at regular intervals if the mouse is not being moved. The parent window should first determine the list item under the cursor by using LBItemFromPt and then draw the insert icon by using the DrawInsert function. By specifying TRUE for the bAutoScroll parameter of LBItemFromPt, you can cause the list box to scroll by one line if the cursor is above or below its client area. The value you return for this notification specifies the type of mouse cursor that the drag list box should set.

The DL_CANCELDRAG notification code is sent if the user cancels a drag operation by clicking the right mouse button or pressing the ESC key. The DL_DROPPED notification code is sent if the user completes a drag operation by releasing the left mouse button, even if the cursor is not over a list item. The drag list box releases the mouse capture before sending either notification. The return value of these two notifications is ignored. Drag List