Click here to Skip to main content
Click here to Skip to main content

Setting the width of the dropdown list

By , 17 May 2000
 
  • Download source files - 17 Kb
  • Sample Image - ComboDropWidth.gif

    Introduction

    One of the more frustrating aspects of a user interface can be the situation where you are presented with a list of choices in a combobox, but are unable to view the choices because the dropdown list is too narrow.

    This article presents an extremely simple CCombobox derived class that will always present a list that is wide enough to hold the widest string.

    A new class

    To start we use the ClassWizard to create a new class CMyComboBox derived from CComboBox.

    Creating a new class

    Then use the class wizard to add an override for the reflected message CBN_DROPDOWN. A reflected message is a message that the control sends to its parent, but which the parent lets the control have a chance at processing first. The "=" before the CBN_DROPDOWN in the ClassWizard indicates it's a reflected message.

    Adding a message handler

    Call the message handler OnDropDown and add the following code

    void CMyComboBox::OnDropdown() 
    {
        RecalcDropWidth();
    }
    

    Then add the function RecalcDropWidth to your CMyComboBox. What we are doing is that each time the combo displays it's drop down, we are intercepting the message and calling a function to quickly check and the size of the control's dropdown before it gets a chance to display it.

    The code for RecalcDropWidth is as follows

    void CMyComboBox::RecalcDropWidth()
    {
        // Reset the dropped width
        int nNumEntries = GetCount();
        int nWidth = 0;
        CString str;
    
        CClientDC dc(this);
        int nSave = dc.SaveDC();
        dc.SelectObject(GetFont());
    
        int nScrollWidth = ::GetSystemMetrics(SM_CXVSCROLL);
        for (int i = 0; i < nNumEntries; i++)
        {
            GetLBText(i, str);
            int nLength = dc.GetTextExtent(str).cx + nScrollWidth;
            nWidth = max(nWidth, nLength);
        }
        
        // Add margin space to the calculations
        nWidth += dc.GetTextExtent("0").cx;
    
        dc.RestoreDC(nSave);
        SetDroppedWidth(nWidth);
    }

    Thanks to Eugeny Berezkin for pointing out that the combo draws its dropdown list with a small margin.

    Essentially what we are doing is getting a device context that we can use to calculate the size of each string to be displayed in the combo. We then ensure that we are performing these calculations with the correct font, and then iterate through the list and work out the maximum width. We then add a small margin to replicate the on-screen behaviour of the drop down. Once that is done we call CComboBox::SetDroppedWidth to set the new width.

    Using the new class

    So - we now have a class that does what we want - but how do we use it?

    Simple. CMyComboBox is a drop-in replacement for CComboBox. Simply include the MyComboBox.h header file where appropriate, and change your combobox's class from CComboBox to CMyComboBox.

    Alternatively, you can use the ClassWizard to associate a variable with your combobox. Go to the Member Variables tab in ClassWizard and select the Form or Dialog class that contains your combobox control. Choose "Add Variable...", specify a name, set the Category as "Control" and then set the variable type as CMyComboBox.

    Subclassing the control

    If you used the MyComboBox files from the download files for this article and simply included them in your project without rebuilding the class file (delete the .clw file from your directory and hit Ctrl+W) then CMyComboBox may not appear in the list of available combobox classes. If this happens simply choose CComboBox and then go into your Form or Dialogs header file and manually change CComboBox to CMyComboBox.

    License

    This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

    About the Author

    Chris Maunder
    Founder CodeProject
    Canada Canada
    Member
    Chris is the Co-founder, Administrator, Architect, Chief Editor and Shameless Hack who wrote and runs The Code Project. He's been programming since 1988 while pretending to be, in various guises, an astrophysicist, mathematician, physicist, hydrologist, geomorphologist, defence intelligence researcher and then, when all that got a bit rough on the nerves, a web developer. He is a Microsoft Visual C++ MVP both globally and for Canada locally.
     
    His programming experience includes C/C++, C#, SQL, MFC, ASP, ASP.NET, and far, far too much FORTRAN. He has worked on PocketPCs, AIX mainframes, Sun workstations, and a CRAY YMP C90 behemoth but finds notebooks take up less desk space.
     
    He dodges, he weaves, and he never gets enough sleep. He is kind to small animals.
     
    Chris was born and bred in Australia but splits his time between Toronto and Melbourne, depending on the weather. For relaxation he is into road cycling, snowboarding, rock climbing, and storm chasing.

    Sign Up to vote   Poor Excellent
    Add a reason or comment to your vote: x
    Votes of 3 or less require a comment

    Comments and Discussions

     
    Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
    You must Sign In to use this message board.
    Search this forum  
        Spacing  Noise  Layout  Per page   
    GeneralMy vote of 5memberAndrehPoffo22 Jan '13 - 7:00 
    GeneralGave you a 5mentorHans Dietrich16 Feb '11 - 2:08 
    GeneralRe: Gave you a 5adminChris Maunder16 Feb '11 - 2:10 
    GeneralRe: Gave you a 5mentorHans Dietrich16 Feb '11 - 2:15 
    GeneralRe: Gave you a 5adminChris Maunder16 Feb '11 - 2:34 
    GeneralRe: Gave you a 5mentorHans Dietrich16 Feb '11 - 2:16 
    GeneralMy vote of 5mentorHans Dietrich16 Feb '11 - 2:07 
    GeneralGreat easy and helpfulmemberjuijuijui18 Aug '09 - 23:36 
    QuestionWhy derive a new class?memberalex__b14 Apr '09 - 19:42 
    QuestionHow to increase the drop down list Height of Comboboxmemberpoda20 Feb '08 - 16:47 
    GeneralNON MFCmemberErnie_D11 Apr '05 - 7:12 
    Generalsetting the combobox width inside a framememberdeepa.n22 Feb '04 - 22:01 
    GeneralThe list box of the combobox is NOT visible when on tab!!sussMaria Efstathiou10 Nov '03 - 0:50 
    GeneralGetting rid of the whitespace that isn't necessary when the scrollbar isn't visible.memberJohn Noël29 Aug '03 - 3:15 
    Generalread a txt file witch selected by a comboboxmembernicolasgib1 Aug '03 - 17:17 
    QuestionHow to make List and Combo Box right aligned?memberDhirendra10 Jun '03 - 3:28 
    AnswerRe: How to make List and Combo Box right aligned?memberdebeyao20 Jul '03 - 14:57 
    GeneralRe: How to make List and Combo Box right aligned?memberrahul.s@s7solutions.com28 Sep '05 - 23:30 
    GeneralRe: How to make List and Combo Box right aligned?membervcplusplus5 May '06 - 7:52 
    QuestionWhy using SaveDC/RestoreDC?memberLarryLeonard9 May '03 - 4:04 
    AnswerRe: Why using SaveDC/RestoreDC?adminChris Maunder9 May '03 - 4:24 
    Generalsetting the <i>ComboBox</i> widthmemberhenchook13 Jan '03 - 20:06 
    GeneralRe: setting the &lt;i&gt;ComboBox&lt;/i&gt; widthmembermangels522 Nov '05 - 1:38 
    Generalon efficiencymemberumeca749 Jan '03 - 0:02 
    GeneralRe: on efficiencymemberJediBecker6 Jun '03 - 12:02 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

    Permalink | Advertise | Privacy | Mobile
    Web03 | 2.6.130516.1 | Last Updated 18 May 2000
    Article Copyright 2000 by Chris Maunder
    Everything else Copyright © CodeProject, 1999-2013
    Terms of Use
    Layout: fixed | fluid