Combo Boxes

A combo box is a unique type of control, defined by the COMBOBOX class, that combines much of the functionality of a list box and an edit control.

This overview describes the types and styles of combo box, the parts of a combo box, the use of an owner-drawn combo box, and how to subclass a combo box. Additional features of combo boxes are also discussed.

The Win32® API provides three types of combo boxes:

There are also a number of combo box styles that define specific properties. For example, two styles enable an application to create an owner-drawn combo box, making the application responsible for displaying information in the control.

A combo box consists of a list and a selection field. The list presents the options that a user can select and the selection field displays the current selection. Except in drop-down list boxes, the selection field is an edit control and can be used to enter text not available in the list.

Combo Box Types and Styles

Combo boxes can be characterized by type and style. Combo box types determine whether the combo box list is a drop-down list and whether the selection field is an edit control. A drop-down list appears only when the user opens it, so it uses less screen space than a list that is always visible. If the selection field is an edit control, the user can enter information not available in the list; otherwise, the user can only select items in the list.

The following table shows the three combo box types and indicates their drop-down list and edit control attributes.

Combo box type

Drop-down list

Edit control

Drop-down combo box

Yes

Yes

Drop-down list box

Yes

No

Simple combo box

No

Yes

 

Combo box styles define specific properties of a combo box. You can combine styles; however some styles only apply to certain combo box types. For a table of combo box styles, see Combo Box Styles.

Combo Box List

A list is the portion of a combo box that displays the items a user can select. Typically, an application initializes the contents of the list when it creates a combo box. Any list item selected by the user is the current selection. In simple and drop-down combo boxes, the user can type in the selection field instead of selecting a list item. In these cases, there is no current selection. For more information, see Current Selection.

List Contents

When an application creates a combo box, it typically initializes the combo box by adding one or more items to the list. Later, an application may add or delete list items, reinitialize the list, or retrieve item information from it.

An application adds list items to a combo box by sending the CB_ADDSTRING message to it. The specified item is added to the end of the list or, in a sorted combo box, in its correct sorted position based on the item's string. In an unsorted combo box, an application can use the CB_INSERTSTRING message to insert an item at a specific position. Once added, a list item is identified by its position.

By using the CB_FINDSTRING or CB_FINDSTRINGEXACT message, an application can determine the position of a list item. CB_FINDSTRING finds an item whose string begins with the specified string. CB_FINDSTRINGEXACT finds an item whose string matches the string exactly. Neither message is case sensitive.

An application can remove a list item by using the CB_DELETESTRING message. If an application needs to reinitialize the combo box list, it can first clear its entire contents by using the CB_RESETCONTENT message. When adding multiple items to the list after a combo box has already been shown, an application can clear the redraw flag to prevent the combo box from being repainted after each item is added. For more information about redrawing, see the description of the WM_SETREDRAW message.

To retrieve the string associated with a list item, an application can use the CB_GETLBTEXT message. The item's string is copied to the buffer specified by the application. To ensure that the buffer is large enough to receive the string, the application can first use the CB_GETLBTEXTLEN message to determine the length of the string. To get the number of list items in a combo box, an application can use the CB_GETCOUNT message.

Current Selection

The current selection is a list item the user has selected; the selected text appears in the selection field of the combo box. However, in the case of a simple combo box or a drop-down combo box, the current selection is only one form of possible user input in a combo box. The user can also type text in the selection field.

The current selection is identified by the zero-based index of the selected list item. An application can set and retrieve it at any time. The parent window or dialog box procedure receives notification when the user changes the current selection for a combo box. The parent window or dialog box is not notified when the application changes the selection.

When a combo box is created, there is no current selection. This is also true for a simple or drop-down combo box, if the user has edited the contents of the selection field. To set the current selection, an application sends the CB_SETCURSEL message to the combo box. An application can also use the CB_SELECTSTRING message to set the current selection to a list item whose string begins with a specified string. To determine the current selection, an application sends the CB_GETCURSEL message to the combo box. If there is no current selection, this message returns CB_ERR.

When the user changes the current selection in a combo box, the parent window or dialog-box procedure receives a WM_COMMAND message with the notification message CBN_SELCHANGE in the high-order word of the wParam parameter. This notification message is not sent when the current selection is set using the CB_SETCURSEL message.

A drop-down combo box or drop-down list box sends the CBN_CLOSEUP notification to the parent window or dialog-box procedure when the drop-down list closes. If the user changed the current selection, the combo box also sends the CBN_SELCHANGE notification when the drop-down list closes. To execute a specific process each time the user selects a list item, you can handle either the CBN_SELCHANGE or CBN_CLOSEUP notification message. Typically, you would wait for the CBN_CLOSEUP notification before processing a change in the current selection. This can be particularly important if a significant amount of processing is required.

An application could also process the notification messages CBN_SELENDOK and CBN_SELENDCANCEL. The system sends CBN_SELENDOK when the user selects a list item, or selects an item and then closes the list. This indicates that the user has finished, and that the selection should be processed. CBN_SELENDCANCEL is sent when the user selects an item, but then selects another control, presses ESC while the drop-down list is open, or closes the dialog box. This indicates that the user's selection should be ignored. CBN_SELENDOK is sent before every CBN_SELCHANGE message.

In a simple combo box, the system sends the CBN_DBLCLK notification message when the user double-clicks a list item. In a drop-down combo box or drop-down list, a single click hides the list, so it is not possible to double-click an item.

Drop-Down Lists

Certain notifications and messages apply only to combo boxes containing drop-down lists. When a drop-down list is open or closed, the parent window of a combo box receives a notification in the form of a WM_COMMAND message. If the list is being opened, the high-order word of wParam is CBN_DROPDOWN. If the list is being closed, it is CBN_CLOSEUP.

An application can open the list of a drop-down combo box or drop-down list box by using the CB_SHOWDROPDOWN message. It can determine whether the list is open by using the CB_GETDROPPEDSTATE message and can determine the coordinates of a drop-down list by using the CB_GETDROPPEDCONTROLRECT message. An application can also increase the width of a drop-down list by using the CB_SETDROPPEDWIDTH message.

Edit Control Selection Fields

The selection field is the portion of a combo box that displays the currently selected list item. In simple and drop-down combo boxes, the selection field is an edit control and can be used to enter text that is not in the list.

An application can retrieve or set the contents of the selection field and can determine or set the edit selection. The application can also limit the amount of text a user can type in the selection field. When the contents of the selection field change, the system sends notification messages to the parent window or dialog box procedure.

To retrieve the content of the selection field, an application can send the WM_GETTEXT message to the combo box. To set the contents of the selection field of a simple or drop-down combo box, an application can send the WM_SETTEXT message to the combo box.

The edit selection is the range of selected text, if any, in the selection field of a simple or drop-down combo box. An application can determine the starting and ending character positions of the current selection by using the CB_GETEDITSEL message. It can also select characters in the edit selection by using the CB_SETEDITSEL message.

Initially, the amount of text that the user can type into the selection field is limited by the size of the selection field. However, if the combo box has the CBS_AUTOHSCROLL style, the text can continue beyond the size of the selection field. An application can use the CB_LIMITTEXT message to limit the amount of text a user can type into the selection field, regardless of whether the control has the CBS_AUTOHSCROLL style.

When the user edits the content of the selection field, the parent window or dialog box procedure receives notification messages. The CBN_EDITUPDATE message is sent first, indicating that the text in the selection field has been edited. After the altered text is displayed, the system sends CBN_EDITCHANGE. When the selection field content changes as the result of a list item being selected, these messages are not sent.

Owner-Drawn Combo Boxes

An application can create an owner-drawn combo box to take responsibility for painting list items. The parent window or dialog box of an owner-drawn combo box (its owner) receives WM_DRAWITEM messages when a portion of the combo box needs to be painted. An owner-drawn combo box can list information other than, or in addition to, text strings. Owner-drawn combo boxes can be of any type. However, the edit control in a simple or drop-down combo box can only display text, while the owner paints the selection field in a drop-down list box.

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

An application can create an owner-drawn combo box by specifying the CBS_OWNERDRAWFIXED or CBS_OWNERDRAWVARIABLE style. If all list items in the combo box are the same height, such as strings or icons, an application can use the CBS_OWNERDRAWFIXED style. If list items are of varying height, like bitmaps of different size, an application can use the CBS_OWNERDRAWVARIABLE style.

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

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

In an owner-drawn combo box, the owner must keep track of list items containing 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. For more information about item data, see Data Associated with List Items. To free data objects associated with items in a combo box, the owner can process the WM_DELETEITEM message.

For an example of an owner-drawn combo box, see Creating an Owner-Drawn Combo Box.

Subclassed Combo Boxes

Subclassing is a procedure that allows an application to intercept and process messages sent or posted to a window. By using subclassing, an application can substitute its own processing for certain messages, while leaving most message processing to the class-defined window procedure.

When the operating system creates a window, it saves information about it in an internal data structure that includes a pointer to the window procedure. To subclass a window, an application calls the SetClassLong function to replace the pointer to that procedure with a pointer to an application-defined subclass procedure. Thereafter, all messages to the window are sent to the subclass procedure. This procedure then uses the CallWindowProc function to pass unprocessed messages to the original window procedure. For a description of the message processing performed by the COMBOBOX class window procedure, see Default Combo Box Behavior.

When the combo box is outside a dialog box, an application cannot process the TAB, ENTER, and ESC keys unless it uses a subclass procedure. When a simple or drop-down combo box receives the input focus, it immediately sets the focus to its child edit control. Therefore, an application must subclass the edit control to intercept keyboard input for a simple or drop-down combo box. For an example of this, see Subclassing a Combo Box.

If a subclass procedure processes the WM_PAINT message, it must use the BeginPaint function to prepare for painting. Before calling the EndPaint function, it passes the device-context (DC) handle as the wParam parameter for the window procedure. If EndPaint is called first, the class window procedure does no painting because EndPaint validates the entire window.

A technique related to subclassing is superclassing. A superclass resembles any other class except that its window procedure does not call DefWindowProc to handle unprocessed messages. Instead, it passes unprocessed messages to the window procedure for the parent window class. Follow the guidelines in Window Procedures to avoid problems that can occur with subclassing and superclassing.

Special Combo Box Features

The Win32 API provides special-purpose messages and functions that enable an application to display a directory listing in a combo box, associate data with list items in a combo box, and change the keyboard interface for a drop-down combo box or drop-down list box.

Directory Lists

An application can add the names of files or subdirectories to a combo box by sending the CB_DIR message to it. The wParam parameter for this message specifies the attributes of the files to add, and the lParam parameter is a pointer to the text string that defines the file specification.

You can use the DlgDirListComboBox function to replace the contents of a combo box in a dialog box. The function fills the combo box with the names of drives, directories, and files that match a specified set of criteria. The DlgDirSelectComboBoxEx function retrieves the current selection in a combo box initialized by DlgDirListComboBox. These functions make it possible for the user to select a drive, directory, or file from a combo box without typing the location and name of the file.

The DlgDirListComboBox and DlgDirSelectComboBoxEx functions and the CB_DIR message are similar to the DlgDirList and DlgDirSelectEx functions and the LB_DIR message used with list boxes.

Data Associated with List Items

An application can associate data with the list items in a combo box. The CB_SETITEMDATA message associates a DWORD value with a list item, and the CB_GETITEMDATA retrieves the value associated with a list item.

The example in Creating an Owner-Drawn Combo Box uses item data to associate a constant with each item in a drop-down list box. Such a unique value identifies each item independent of its sorted position.

Other applications might use item data to associate a handle or pointer with a list item. If so, an application can process a WM_DELETEITEM message to delete or free the specified object when the list item is deleted

The Extended User Interface

Drop-down combo boxes and drop-down list boxes support an alternative keyboard interface called the extended user interface. By default, the F4 key opens or closes the list, and the DOWN ARROW changes the current selection. In a combo box with the extended user interface, however, the F4 key is disabled and pressing the DOWN ARROW key opens the drop-down list.

To select the user interface for a combo box, an application can send the CB_SETEXTENDEDUI message to the combo box. A TRUE value for the wParam parameter enables the extended user interface; a FALSE value sets the default user interface. To determine whether a combo box uses the extended user interface, an application can send the CB_GETEXTENDEDUI message to the combo box.

Combo Box Notifications

Messages from combo boxes are sent as notifications in the form of WM_COMMAND messages. The notification message is stored in the high word of the wParam parameter, and an application can process the following combo box notification messages.

Notification message

Description

CBN_CLOSEUP

Indicates the list in a drop-down combo box or drop-down list box is about to close.

CBN_DBLCLK

Indicates the user has double-clicked a list item in a simple combo box.

CBN_DROPDOWN

Indicates the list in a drop-down combo box or drop-down list box is about to open.

CBN_EDITCHANGE

Indicates the user has changed the text in the edit control of a simple or drop-down combo box. This notification message is sent after the altered text is displayed.

CBN_EDITUPDATE

Indicates the user has changed the text in the edit control of a simple or drop-down combo box. This notification message is sent before the altered text is displayed.

CBN_ERRSPACE

Indicates the combo box cannot allocate enough memory to carry out a request, such as adding a list item.

CBN_KILLFOCUS

Indicates the combo box is about to lose the input focus.

CBN_SELCHANGE

Indicates the current selection has changed.

CBN_SELENDCANCEL

Indicates that the selection made in the drop down list, while it was dropped down, should be ignored.

CBN_SELENDOK

Indicates that the selection made drop down list, while it was dropped down, should be accepted.

CBN_SETFOCUS

Indicates the combo box has received the input focus.

Default Combo Box Behavior

This following table describes the messages specifically handled by the predefined COMBOBOX class window procedure.

Message

Description

CB_ADDSTRING

Sends an LB_ADDSTRING message to the list window to add a list item.

CB_DELETESTRING

Sends an LB_DELETESTRING message to the list window to delete a list item.

CB_DIR

Adds the file names matching the specified attributes and path to the list.

CB_FINDSTRING

Sends an LB_FINDSTRING message to the list window. This message returns the index of the first list item that begins with the specified text.

CB_FINDSTRINGEXACT

Sends an LB_FINDSTRING message to the list window. This message returns the index of the first list item exactly matching the specified text.

CB_GETCOUNT

Sends an LB_GETCOUNT message to the list window. It returns the number of list items.

CB_GETCURSEL

Sends an LB_GETCURSEL message to the list window. It returns the index of the currently selected item, if any.

CB_GETDROPPEDCONTROLRECT

Fills the specified rectangle structure with the screen coordinates of a drop-down list.

CB_GETDROPPEDSTATE

Returns TRUE if a drop-down list is open; otherwise, it returns FALSE.

CB_GETDROPPEDWIDTH

Returns the minimum allowable width, in pixels, of the drop-down list.

CB_GETEDITSEL

Sends an EM_GETSEL message to the edit control, and it returns the starting and ending position of the current selection. In drop-down list boxes, the window procedure returns CB_ERR.

CB_GETEXTENDEDUI

Returns TRUE if the combo box is a drop-down combo box or drop-down list box and the extend user-interface flag is set; otherwise, it returns FALSE.

CB_GETHORIZONTALEXTENT

Sends an LB_GETHORIZONTALEXTENT message to the list window. It returns the scrollable width, in pixels, of the drop-down list.

CB_GETITEMDATA

Sends an LB_GETITEMDATA message to the list window. It returns the value associated with the specified list item.

CB_GETITEMHEIGHT

Sends an LB_GETITEMHEIGHT message to the list window. It returns the height, in pixels, of the specified owner-drawn list item.

CB_GETLBTEXT

Sends an LB_GETTEXT message to the list window. It copies the specified list text to the specified buffer.

CB_GETLBTEXTLEN

Sends an LB_GETTEXTLEN message to the list window. It returns the length, in TCHARs, of the specified list text.

CB_GETLOCALE

Sends an LB_GETLOCALE message to the list window. It returns the current locale for the list.

CB_GETTOPINDEX

Sends an LB_GETTOPINDEX message to the list window. It returns the index of the first visible item in the drop-down list.

CB_INITSTORAGE

Sends an LB_INITSTORAGE message to the list window. It initializes space for the specified number of items and the specified number of bytes for item strings.

CB_INSERTSTRING

Sends an LB_INSERTSTRING message to the list window. It inserts a list item at the specified position.

CB_LIMITTEXT

Sends an EM_LIMITTEXT message to the edit control. It sets the maximum number of characters a user can enter in the edit control. In drop-down list boxes, the window procedure returns CB_ERR.

CB_RESETCONTENT

Sends an LB_RESETCONTENT message to the list window, and it removes the contents of the list.

CB_SELECTSTRING

Sends an LB_SELECTSTRING message to the list window. It selects the first list item, if any, that begins with the characters in the specified text.

CB_SETCURSEL

Sends an LB_SETCURSEL message to the list window, and it sets the current selection.

CB_SETDROPPEDWIDTH

Sets the minimum allowable width, in pixels, of the drop down list.

CB_SETEDITSEL

Sends an EM_SETSEL message to the edit control. It selects the specified range of text. In drop-down list boxes, the window procedure returns CB_ERR.

CB_SETEXTENDEDUI

Sets or clears the extended user-interface flag. This flag changes the keys that open and close the list in a drop-down combo box or drop-down list box. If the combo box is a simple combo box, the window procedure returns CB_ERR.

CB_SETHORIZONTALEXTENT

Sends an LB_SETHORIZONTALEXTENT message to the list window. It sets the scrollable width, in pixels, of the drop down list.

CB_SETITEMDATA

Sends an LB_SETITEMDATA message to the list window. It associates the specified value with a list item.

CB_SETITEMHEIGHT

Sends an LB_SETITEMHEIGHT message to the list window. It sets the height of the specified owner-drawn list item or the selection field.

CB_SETLOCALE

Sends an LB_SETLOCALE message to the list window, and it sets the current locale for the list. The locale affects how the list is sorted if it has the CBS_SORT style and strings are added using CB_ADDSTRING.

CB_SETTOPINDEX

Sends an LB_SETTOPINDEX message to the list window. It scrolls the drop-down list so the specified item is at the top of the visible range.

CB_SHOWDROPDOWN

Shows or hides the drop-down list. This message has no effect on simple combo boxes.

WM_CHAR

Processes character input. In drop-down list boxes, this message is passed to the list window, which moves the selection to the first item beginning with the specified character. In simple and drop-down combo boxes, this message is passed to the edit control.

WM_CLEAR

Deletes the edit selection. In simple and drop-down combo boxes, the edit control processes this message. In drop-down list boxes, the window procedure returns CB_ERR.

WM_COMMAND

Processes notification messages from the edit control and list window and sends corresponding combo box notification messages to the parent window.

 

For edit control notifications, the window procedure may update the list window's current selection, caret index, and top index. For list notification messages, the window procedure may update the content of the selection field.

WM_COMPAREITEM

Passes the message to the parent window, enabling the application to specify the relative sort position of two owner-drawn list items. The combo box window receives this message from the list window.

WM_COPY

Copies the edit selection to the clipboard. In simple and drop-down combo boxes, the edit control processes this message. In drop-down list boxes, the window procedure returns CB_ERR.

WM_CREATE

Initializes the combo box.

WM_CUT

Deletes the edit selection and places it on the clipboard. In simple and drop-down combo boxes, the edit control processes this message. In drop-down list boxes, the window procedure returns CB_ERR.

WM_DELETEITEM

Passes the message to the parent window, notifying the application that a list item has been deleted. The combo box window receives this message from the list window.

WM_DRAWITEM

Passes the message on to the parent window enabling the application to paint the specified list item. The combo box window receives this message from the list window. The window procedure can also originate this message to have the application paint the selection field of a drop-down list box.

WM_ENABLE

Sets the state to enable or prohibit mouse and keyboard input.

WM_ERASEBKGND

Returns 1, indicating that the background is erased.

WM_GETDLGCODE

Returns a combination of the DLG_WANTCHARS and DLGC_WANTARROWS values.

WM_GETFONT

Returns the handle to the current font with which the combo box will draw its text.

WM_GETTEXT

Copies the contents of the selection field to the specified buffer. In simple and drop-down combo boxes, the edit control processes this message.

WM_GETTEXTLENGTH

Returns the length, in characters, of the text in the selection field. In simple and drop-down combo boxes, the edit control processes this message.

WM_KEYDOWN

Processes noncharacter keyboard input. In drop-down list boxes, this message is sent to the list window, which may show or hide itself, or change its current selection or caret index. In simple and drop-down combo boxes, this message is passed to the edit control. The edit control passes certain keys to the list window, such as the UP and DOWN ARROW keys and the F4 key.

WM_KILLFOCUS

Hides the highlight in the selection field and closes the drop-down list, if necessary. If the window receiving the input focus is part of the combo box (for example, the edit control), this message is ignored.

WM_LBUTTONDBLCLK

Same as WM_LBUTTONDOWN.

WM_LBUTTONDOWN

Sets the focus to the combo box and, for drop-down combo boxes and drop-down lists, can open or close the list. If it opens the list, the window procedure captures the mouse to enable selection by dragging and releasing the mouse button.

WM_LBUTTONUP

Releases the mouse capture if the mouse opened the list.

WM_MEASUREITEM

Posts the message to the parent window, enabling the application to modify the contents of the specified MEASUREITEMSTRUCT structure. The combo box window receives this message from the list window.

WM_MOUSEMOVE

Posts the message to the list window if the mouse has opened the list and the mouse button is still down. This enables a user to select an item by dragging the mouse pointer to a list item and then releasing the button.

WM_NCCREATE

Allocates an internal data structure used by the combo box window procedure.

WM_NCDESTROY

Frees resources allocated in response to the WM_NCCREATE message.

WM_PAINT

Paints the invalid region of the combo box. If wParam is not NULL, it is assumed to be a DC handle passed from a subclass function. The window procedure uses the specified DC instead of calling BeginPaint and EndPaint.

WM_PASTE

Replaces the edit selection with the contents of the clipboard. In simple and drop-down combo boxes, the edit control processes this message. In drop-down list boxes, the window procedure returns CB_ERR.

WM_SETFOCUS

Sets the focus to the edit control or, in drop-down list boxes, inverts the selection field and turns on the caret in the list window.

WM_SETFONT

Saves the specified font handle in an internal structure, adjusts the dimensions of the selection field and list, and invalidates the combo box window. Text in the selection field and the list is displayed in the saved font.

WM_SETREDRAW

Sets or clears the redraw flag. If the redraw flag is cleared, the combo box is not repainted until the flag is set again.

WM_SETTEXT

Sets the contents of the edit control. In simple and drop-down combo boxes, the edit control processes this message. In drop-down list boxes, the window procedure returns CB_ERR.

WM_SIZE

Resizes the child windows, if necessary.

WM_SYSKEYDOWN

Opens or closes the drop-down list depending on which arrow key the user pressed.

 

All other messages are passed to the DefWindowProc function for default processing.