MORE INFORMATION
The combo box in Windows is actually a combination of two or more controls;
that's why it's called a "combo" box. For more information about the parts
of a combo box and how they relate to each other, please see the following
article in the Microsoft Knowledge Base:
65881
The Parts of a Windows Combo Box and How They Relate
To make the combo box list wider or narrower, you need the handle of the
list box control within the combo box. This task is difficult because the
list box is actually a child of the desktop window (for CBS_DROPDOWN and
CBS_DROPDOWNLIST styles). If it were a child of the ComboBox control,
dropping down the list box would clip it to the parent, and it wouldn't
display.
A combo box receives WM_CTLCOLOR messages for its component controls when
they need to be painted. This allows the combo box to specify a color for
these controls. The HIWORD of the lParam in this message is the type of the
control. In case of the combo box, Windows sends it a WM_CTLCOLOR message
with the HIWORD set to CTLCOLOR_LISTBOX when the list box control needs to
be painted. The LOWORD of the lParam contains the handle of the list box
control.
In 32-bit Windows, the WM_CTLCOLOR message has been replaced with multiple
messages, one for each type of control (WM_CTLCOLORBTN). For more
information about this, please see the following article in the Microsoft
Knowledge Base:
81707
WM_CTLCOLOR Processing for Combo Boxes of All Styles
Once you obtain the handle to the list box control window, you can resize
the control by using the MoveWindow API.
The following code sample demonstrates how to do this. This sample assumes
that you have placed the combo box control in a dialog box.
Sample Code
// Global declarations.
LRESULT CALLBACK NewComboProc (HWND hWnd, UINT message, WPARAM
wParam, LPARAM lParam ); // prototype for the combo box subclass proc
HANDLE hInst; // Current app instance.
BOOL bFirst; // A flag.
// Dialog procedure for the dialog containing the combo box.
BOOL __export CALLBACK DialogProc(HWND hDlg, UINT message, WPARAM
wParam, LPARAM lParam)
{
FARPROC lpfnNewComboProc;
switch (message)
{
case WM_INITDIALOG:
bFirst = TRUE; // Set flag here - see below for usage.
// Subclass the combo box.
lpfnOldComboProc = (FARPROC ) SetWindowLong (
GetDlgItem ( hDlg, IDC_COMBO1 ),
GWL_WNDPROC,
(LONG)NewComboProc );
break;
case WM_DESTROY:
(FARPROC ) SetWindowLong ( GetDlgItem ( hDlg, IDC_COMBO1 ),
GWL_WNDPROC,
(LONG)lpfnOldComboProc );
break;
default:
break;
}
return FALSE;
} // End dialog proc.
// Combobox subclass proc.
LRESULT CALLBACK NewComboProc (HWND hWnd, UINT message, WPARAM
wParam, LPARAM lParam );
{
static HWND hwndList;
static RECT rectList;
#ifdef WIN16
if ( WM_CTLCOLOR == message) // Combo controls are to be painted.
#else
if ( WM_CTLCOLORLISTBOX == message ) // 32 bits has new message.
#endif
{
// Is this message for the list box control in the combo?
#ifdef WIN16
if (CTLCOLOR_LISTBOX==HIWORD (lParam) ) // Need only for 16 bits.
{
#endif
// Do only the very first time, get the list
// box handle and the list box rectangle.
// Note the use of GetWindowRect, as the parent
// of the list box is the desktop window
if ( bFirst )
{
#ifdef WIN16
hwndList = LOWORD (lParam );
#else
hwndList = (HWND) lParam ; // HWND is 32 bits.
#endif
GetWindowRect ( hwndList, &rectList );
bFirst = FALSE;
}
// Resize listbox window cx by 50 (use your size here).
MoveWindow ( hwndList, rectList.left, rectList.top,
( rectList.right - rectList.left + 50 ),
rectList.bottom - rectList.top, TRUE );
#ifdef WIN16
}
#endif
}
// Call original combo box procedure to handle other combo messages.
return CallWindowProc ( lpfnOldComboProc, hWnd, message,
wParam, lParam );
}