How to Modify the Width of the Drop Down List in a Combo Box

Last reviewed: September 29, 1995
Article ID: Q131845
The information in this article applies to:
  • Microsoft Windows Software Development Kit (SDK) version 3.1
  • Microsoft Win32 Application Programming Interface (API) included with:

        - Microsoft Windows NT version 3.51
        - Microsoft Windows 95 version 4.0
        - Microsoft Win32s version 1.3
    

SUMMARY

The Windows combo box contains a list box (of the ComboLBox class) within it. In the standard combo box, this list box has exactly the same width as the combo box. However, you can make the width of the list box wider or narrower than the width of the combo box. You may have seen combo box lists like this in Microsoft Word and Microsoft Excel. This article shows by example how to subclass a standard combo box class to achieve this functionality.

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:

   ARTICLE-ID: Q65881
   TITLE     : 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:

   ARTICLE-ID: Q81707
   TITLE     : 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 ); }


Additional reference words: 1.20 3.10 3.50 4.00 95
KBCategory: kbui kbcode
KBSubcategory: UsrCtl


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: September 29, 1995
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.