ComboBoxEx Controls are an extension of the combo box control that provides native support for item images. To make item images easily accessible, the control provides image list support. By using this control, you can provide the functionality of a combo box without having to manually draw item graphics.
Effectively, a ComboBoxEx control creates a child combo box and performs owner draw tasks for you based on an assigned image list. Therefore, the CBS_OWNERDRAWFIXED style is implied and you need not use it when creating the control. Because image lists are used to provide item graphics, the CBS_OWNERDRAWVARIABLE style cannot be used.
A ComboBoxEx control must be initialized by calling the
You can create a ComboBoxEx control by using the
ComboBoxEx controls are created without a default image list. To use item
images, you must create an image list for the ComboBoxEx control and assign it
to the control using the
ComboBoxEx controls support only the following ComboBox styles:
There are also several
Because the ComboBoxEx control performs owner draw tasks for you based on an assigned image list, the CBS_OWNERDRAWFIXED style is implied; you need not use it when creating the control. Because image lists are used to provide item graphics, the CBS_OWNERDRAWVARIABLE style cannot be used. The ComboBoxEx control also supports ComboBoxEx Control Extended Styles that provide additional features.
ComboBoxEx controls maintain item information using a
The ComboBoxEx control provides easy access to and manipulation of items
through messaging. To add or delete an item, send the
ComboBoxEx controls support callback item attributes. You can specify an item as a callback item when you add it to the control using CBEM_INSERTITEM. When you assign values to an item's COMBOBOXEXITEM structure, you must specify the appropriate callback flag values. The following are COMBOBOXEXITEM structure members and their corresponding callback flag values.
| Member | Callback value |
|---|---|
| pszText | LPSTR_TEXTCALLBACK |
| iImage | I_IMAGECALLBACK |
| iSelectedImage | I_IMAGECALLBACK |
| iOverlay | I_IMAGECALLBACK |
| iIndent | I_INDENTCALLBACK |
The control will request information about callback items by sending
If you want a ComboBoxEx control to display icons with items, you must provide an image list. ComboBoxEx controls support up to three images for an item—one for its selected state, one for its nonselected state, and one for an overlay image. Assign an existing image list to a ComboBoxEx control using the CBEM_SETIMAGELIST message.
The COMBOBOXEXITEM structure contains members that represent the image indexes for each image list (selected, unselected, and overlay). For each item, set these members to display the desired images. It is not necessary to specify image indexes for each type of image. You can mix and match image types as you like, but always set the mask member of the COMBOBOXEXITEM structure to indicate which members are being used. The control ignores members that have not been flagged as valid.
A ComboBoxEx control sends notification messages to report changes within
itself or to request callback item information. The parent of the control
receives all
Following are the ComboBoxEx-specific notification messages.
| Notification | Description |
|---|---|
| Signals that the user has activated the drop-down list or clicked in the control's edit box. | |
| Signals that the user has selected an item from the drop-down list or has concluded an edit operation within the edit box. | |
| Reports that an item was deleted. | |
| Requests information about an item's attributes. | |
| Signals that an item was inserted in the control. |
The following are the standard combo box messages that a ComboBoxEx control forwards to its child combo box. Some of these messages may be processed by the ComboBoxEx control either before or after the message has been forwarded.
Following are the windows messages that a ComboBoxEx control forwards to its parent window:
This section contains sample code and information about the following topics related to ComboBoxEx controls:
To create a ComboBoxEx control, call the CreateWindowEx function, using WC_COMBOBOXEX as the window class. You must first register the window class by calling the InitCommonControlsEx function, while specifying the ICC_USEREX_CLASSES bit in the accompanying INITCOMMONCONTROLSEX structure.
The following application-defined function creates a ComboBoxEx control with the CBS_DROPDOWN style in the main window.
// CreateComboEx - Registers the ComboBoxEx window class and creates
// a ComboBoxEx control in the client area of the main window.
//
// g_hwndMain - A handle to the main window.
// g_hinst - A handle to the program instance.
HWND WINAPI CreateComboEx(void)
{
HWND hwnd;
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_USEREX_CLASSES;
InitCommonControlsEx(&icex);
hwnd = CreateWindowEx(0, WC_COMBOBOXEX, NULL,
WS_BORDER | WS_VISIBLE |
WS_CHILD | CBS_DROPDOWN,
// No size yet--resize after setting image list.
0, // Vertical position of Combobox
0, // Horizontal position of Combobox
0, // Sets the width of Combobox
100, // Sets the height of Combobox
g_hwndMain,
NULL,
g_hinst,
NULL);
return (hwnd);
}
To add an item to a ComboBoxEx control, first define a COMBOBOXEXITEM structure. Set the mask member of the structure to indicate which members you want the control to use. Set the specified members of the structure to the values you want, and then send the CBEM_INSERTITEM message to add the item to the control.
The following application-defined function adds 15 items to an existing ComboBoxEx control. Note that the mask member of the COMBOBOXEXITEM structure includes flag values that tell the control to display images for each item.
#define MAX_ITEMS 15
// AddItems - Uses the CBEM_INSERTITEM message to add items to an
// existing ComboBoxEx control.
BOOL WINAPI AddItems(HWND hwndCB)
{
// Declare and init locals.
COMBOBOXEXITEM cbei;
int iCnt;
typedef struct {
int iImage;
int iSelectedImage;
int iIndent;
LPTSTR pszText;
} ITEMINFO, *PITEMINFO;
ITEMINFO IInf[ ] = {
{ 0, 3, 0, "first"},
{ 1, 4, 1, "second"},
{ 2, 5, 2, "third"},
{ 0, 3, 0, "fourth"},
{ 1, 4, 1, "fifth"},
{ 2, 5, 2, "sixth"},
{ 0, 3, 0, "seventh"},
{ 1, 4, 1, "eighth"},
{ 2, 5, 2, "ninth"},
{ 0, 3, 0, "tenth"},
{ 1, 4, 1, "eleventh"},
{ 2, 5, 2, "twelfth"},
{ 0, 3, 0, "thirteenth"},
{ 1, 4, 1, "fourteenth"},
{ 2, 5, 2, "fifteenth"}
};
// Set the mask common to all items.
cbei.mask = CBEIF_TEXT | CBEIF_INDENT |
CBEIF_IMAGE| CBEIF_SELECTEDIMAGE;
for(iCnt=0;iCnt<MAX_ITEMS;iCnt++){
// Initialize the COMBOBOXEXITEM struct.
cbei.iItem = iCnt;
cbei.pszText = IInf[iCnt].pszText;
cbei.cchTextMax = sizeof(IInf[iCnt].pszText);
cbei.iImage = IInf[iCnt].iImage;
cbei.iSelectedImage = IInf[iCnt].iSelectedImage;
cbei.iIndent = IInf[iCnt].iIndent;
// Tell the ComboBoxEx to add the item. Return FALSE if
// this fails.
if(SendMessage(hwndCB,CBEM_INSERTITEM,0,(LPARAM)&cbei) == -1)
return FALSE;
}
// Assign the existing image list to the ComboBoxEx control
// and return TRUE.
SendMessage(hwndCB,CBEM_SETIMAGELIST,0,(LPARAM)g_himl);
// Set size of control to make sure it's displayed correctly now
// that the image list is set.
SetWindowPos(hwndCB,NULL,20,20,250,120,SWP_NOACTIVATE);
return TRUE;
}
If your application is going to use callback items in a ComboBoxEx control, it must be prepared to handle the CBEN_GETDISPINFO notification message. A ComboBoxEx control sends this notification whenever it needs the owner to provide specific item information. For more information about callback items, see Callback Items.
The following application-defined function processes CBEN_GETDISPINFO by providing attributes for a given item. Note that it sets the mask member of the incoming COMBOBOXEXITEM structure to CBEIF_DI_SETITEM. Setting mask to this value makes the control retain the item information so it will not need to request the information again.
Show Example
// DoItemCallback - Processes CBEN_GETDISPINFO by providing item
// attributes for a given callback item.
void WINAPI DoItemCallback(PNMCOMBOBOXEX pNMCBex)
{
DWORD dwMask = pNMCBex->ceItem.mask;
if(dwMask & CBEIF_TEXT)
;// Provide item text.
if(dwMask & CBEIF_IMAGE)
;// Provide an item image index.
/*
* Provide other callback information as desired.
*/
// Make the ComboBoxEx control hold onto the item information.
pNMCBex->ceItem.mask = CBEIF_DI_SETITEM;
}
A ComboBoxEx control notifies its parent window of events by sending WM_NOTIFY messages. Because the control uses a child combo box, it forwards all WM_COMMAND notification messages it receives to the parent window to be processed. Therefore, your application must be prepared to process WM_NOTIFY messages from the ComboBoxEx and WM_COMMAND messages forwarded from the ComboBoxEx child combo box control.
The example in this section handles the WM_NOTIFY and WM_COMMAND messages from a ComboBoxEx control by calling a corresponding application-defined function to process them.
LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg){
case WM_COMMAND:
// If this is an "old style" combo box notification, handle it.
if((HWND)lParam == g_hwndCB)
DoOldNotify(hwnd, wParam);
break;
case WM_NOTIFY:
return (DoCBEXNotify(hwnd, lParam));
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
break;
}
return FALSE;
}