To create a ComboBoxEx control specify WC_COMBOBOXEX as the window class and to register the class set the ICC_USEREX_CLASSES flag for the dwICC member of the INITCOMMONCONTROLSEX structure.
To use item images, an image list is created and assigned to the control using the CBEM_SETIMAGELIST message. 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.
///ComboBoxEx Control Example
#define IDC_COMBOBOXEX 1
#define IDC_STATIC_ICON 2
#define IDC_STATIC_TEXT 3
#include <windows.h>
#include <commctrl.h>
#pragma comment(lib, "comctl32.lib")
void CreateComboEx();
HWND hwndComBoxEx,hwndStaticText,hwndStaticIcon;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
MSG msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = TEXT("myWindowClass");
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wc);
CreateWindowEx(WS_EX_CLIENTEDGE,TEXT("myWindowClass"),TEXT("ComboBoxEx Control"), WS_VISIBLE | WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, 430, 200, NULL, NULL, hInstance, NULL);
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
{
HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
HBITMAP bitmapicon;
// load common control class ICC_USEREX_CLASSES from the dynamic-link library (DLL).
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_USEREX_CLASSES;
InitCommonControlsEx(&icex);
//create combo box
hwndComBoxEx = CreateWindowEx(0, WC_COMBOBOXEX, NULL,WS_BORDER | WS_VISIBLE |WS_CHILD | CBS_DROPDOWN,10,10, 200,100,hwnd,(HMENU)IDC_COMBOBOXEX,NULL,NULL);
//create static boxed. One for text the other to display images
hwndStaticIcon = CreateWindow(TEXT("static"), TEXT(""), WS_CHILD |SS_ICON| WS_VISIBLE,230, 15, 40, 40, hwnd, (HMENU)IDC_STATIC_ICON, NULL, NULL);
hwndStaticText = CreateWindow(TEXT("static"), TEXT(""), WS_CHILD |WS_VISIBLE,270, 15, 150, 40, hwnd, (HMENU)IDC_STATIC_TEXT, NULL, NULL);
//create custom font
HFONT font = CreateFont(30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TEXT("Times New Roman"));
//Set font in both comboboxex and static box
SendMessage (hwndComBoxEx, WM_SETFONT, (WPARAM)font, TRUE);
SendMessage (hwndStaticText, WM_SETFONT, (WPARAM)font, TRUE);
//USed to set up items in ComboBoxEx control
COMBOBOXEXITEM cbei;
cbei.mask = CBEIF_TEXT | CBEIF_IMAGE| CBEIF_SELECTEDIMAGE;// Set the mask common to all items.
typedef struct {LPTSTR pszText;int iImage;int iSelectedImage;} ITEMINFO;
ITEMINFO IInf[] = {
{TEXT("Chilli"),0, 0 },
{TEXT("Mushroom"), 1, 1 },
{TEXT("Onion"), 2, 2},
{TEXT("Pineapple"), 3, 3},
{TEXT("Strawberry"),4, 4}};
//load BMP images from project folder and insert into image list im_list
HIMAGELIST im_list = ImageList_Create(32, 32,ILC_COLOR|ILC_MASK, 4, 0);
bitmapicon = (HBITMAP)LoadImage(NULL, TEXT("chilli.bmp"), IMAGE_BITMAP, 32, 32, LR_LOADFROMFILE);
ImageList_Add(im_list,bitmapicon,0);
bitmapicon = (HBITMAP)LoadImage(NULL, TEXT("mushroom.bmp"), IMAGE_BITMAP, 32, 32, LR_LOADFROMFILE);
ImageList_Add(im_list,bitmapicon,0);
bitmapicon = (HBITMAP)LoadImage(NULL, TEXT("onion.bmp"), IMAGE_BITMAP, 32, 32, LR_LOADFROMFILE);
ImageList_Add(im_list,bitmapicon,0);
bitmapicon = (HBITMAP)LoadImage(NULL, TEXT("pineapple.bmp"), IMAGE_BITMAP, 32, 32, LR_LOADFROMFILE);
ImageList_Add(im_list,bitmapicon,0);
bitmapicon = (HBITMAP)LoadImage(NULL, TEXT("strawberry.bmp"), IMAGE_BITMAP, 32, 32, LR_LOADFROMFILE);
ImageList_Add(im_list,bitmapicon,0);
SendMessage(hwndComBoxEx, CBEM_SETIMAGELIST, 0, (LPARAM)im_list);
//populate comboboxex with data
for(int iCnt=0;iCnt<5;iCnt++){
cbei.iItem = iCnt;
cbei.pszText = IInf[iCnt].pszText;
cbei.cchTextMax = sizeof(IInf[iCnt].pszText);
cbei.iImage = IInf[iCnt].iImage;
cbei.iSelectedImage = IInf[iCnt].iSelectedImage;
// Tell the ComboBoxEx items. Return FALSE if this fails.
if(SendMessage(hwndComBoxEx,CBEM_INSERTITEM,0,(LPARAM)&cbei) == -1)
return FALSE;
}
}
break;
case WM_COMMAND:
//checks combo box clicked
if((HWND)lParam ==hwndComBoxEx)
{
//detects selection change in comboxboxec
if ( HIWORD(wParam) == 5) {
/* Could be used just to get selected item and text
TCHAR strText[255];
LRESULT sel = SendMessage(hwndComBoxEx, CB_GETCURSEL, 0, 0);
SendMessage(hwndComBoxEx,CB_GETLBTEXT, sel,(LPARAM)strText);
*/
//used to obstain selected item data by sending CBEM_GETITEM to ComBoxEx
TCHAR buff[100];
COMBOBOXEXITEM info;
info.mask = CBEIF_TEXT| CBEIF_IMAGE| CBEIF_SELECTEDIMAGE;;
info.iItem = SendMessage( hwndComBoxEx, CB_GETCURSEL, 0, 0 );
info.pszText = buff;
info.cchTextMax = sizeof( buff );
SendMessage(hwndComBoxEx, CBEM_GETITEM, 0, (LPARAM)&info );
//get image list from comboboxex and extract selected individual image
HIMAGELIST im_list=(HIMAGELIST)SendMessage( hwndComBoxEx, CBEM_GETIMAGELIST, 0, 0 );
int im_index=info.iSelectedImage;
HICON selectedicon=ImageList_GetIcon(im_list,im_index, NULL );
//set up static box with selected text and image
SendMessage(hwndStaticIcon, STM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)selectedicon);
SetWindowText(hwndStaticText, buff);
//redraw static text box after change
RECT rect;
GetClientRect(hwndStaticText, &rect);
InvalidateRect(hwndStaticText, &rect, TRUE);
MapWindowPoints(hwndStaticText, hwnd, (POINT *) &rect, 2);
RedrawWindow(hwnd, &rect, NULL, RDW_ERASE | RDW_INVALIDATE);
}
} break;
//change appearance of both static windows
case WM_CTLCOLORSTATIC:
{
if (GetDlgCtrlID((HWND)lParam) == IDC_STATIC_TEXT || GetDlgCtrlID((HWND)lParam) == IDC_STATIC_ICON)
{
HDC hdcStatic = (HDC)wParam;
SetTextColor(hdcStatic, RGB(255, 0, 0)); //set text color
return (LRESULT)GetStockObject(NULL_BRUSH);//set background to white
}
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}