Click here to Skip to main content
15,879,326 members
Articles / Desktop Programming / MFC
Article

Setting the width of the dropdown list

Rate me:
Please Sign up or sign in to vote.
4.98/5 (33 votes)
17 May 2000CPOL 353.5K   2.7K   104   50
A simple tutorial explaining how to set the width of a combo dropdown list so that all items are fully visible
  • 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)


    Written By
    Founder CodeProject
    Canada Canada
    Chris Maunder is the co-founder of CodeProject and ContentLab.com, and has been a prominent figure in the software development community for nearly 30 years. Hailing from Australia, Chris has a background in Mathematics, Astrophysics, Environmental Engineering and Defence Research. His programming endeavours span everything from FORTRAN on Super Computers, C++/MFC on Windows, through to to high-load .NET web applications and Python AI applications on everything from macOS to a Raspberry Pi. Chris is a full-stack developer who is as comfortable with SQL as he is with CSS.

    In the late 1990s, he and his business partner David Cunningham recognized the need for a platform that would facilitate knowledge-sharing among developers, leading to the establishment of CodeProject.com in 1999. Chris's expertise in programming and his passion for fostering a collaborative environment have played a pivotal role in the success of CodeProject.com. Over the years, the website has grown into a vibrant community where programmers worldwide can connect, exchange ideas, and find solutions to coding challenges. Chris is a prolific contributor to the developer community through his articles and tutorials, and his latest passion project, CodeProject.AI.

    In addition to his work with CodeProject.com, Chris co-founded ContentLab and DeveloperMedia, two projects focussed on helping companies make their Software Projects a success. Chris's roles included Product Development, Content Creation, Client Satisfaction and Systems Automation.

    Comments and Discussions

     
    QuestionBorder took space Pin
    Member 568844320-Sep-18 4:43
    Member 568844320-Sep-18 4:43 
    QuestionAverage character width Pin
    Member 568844320-Sep-18 4:37
    Member 568844320-Sep-18 4:37 
    Question5* Pin
    jsp2314-Aug-15 0:21
    jsp2314-Aug-15 0:21 
    QuestionNice, thank you! Pin
    J Eakin3-Apr-14 11:46
    J Eakin3-Apr-14 11:46 
    GeneralMy vote of 5 Pin
    AndrehPoffo22-Jan-13 7:00
    AndrehPoffo22-Jan-13 7:00 
    GeneralGave you a 5 Pin
    Hans Dietrich16-Feb-11 2:08
    mentorHans Dietrich16-Feb-11 2:08 
    GeneralRe: Gave you a 5 Pin
    Chris Maunder16-Feb-11 2:10
    cofounderChris Maunder16-Feb-11 2:10 
    GeneralRe: Gave you a 5 Pin
    Hans Dietrich16-Feb-11 2:15
    mentorHans Dietrich16-Feb-11 2:15 
    GeneralRe: Gave you a 5 Pin
    Chris Maunder16-Feb-11 2:34
    cofounderChris Maunder16-Feb-11 2:34 
    GeneralRe: Gave you a 5 Pin
    Hans Dietrich16-Feb-11 2:16
    mentorHans Dietrich16-Feb-11 2:16 
    GeneralMy vote of 5 Pin
    Hans Dietrich16-Feb-11 2:07
    mentorHans Dietrich16-Feb-11 2:07 
    GeneralGreat easy and helpful Pin
    juijuijui18-Aug-09 23:36
    juijuijui18-Aug-09 23:36 
    QuestionWhy derive a new class? Pin
    alex__b14-Apr-09 19:42
    professionalalex__b14-Apr-09 19:42 
    QuestionHow to increase the drop down list Height of Combobox Pin
    poda20-Feb-08 16:47
    poda20-Feb-08 16:47 
    GeneralNON MFC Pin
    Ernie_D11-Apr-05 7:12
    Ernie_D11-Apr-05 7:12 
    Generalsetting the combobox width inside a frame Pin
    Member 89982722-Feb-04 22:01
    Member 89982722-Feb-04 22:01 
    GeneralThe list box of the combobox is NOT visible when on tab!! Pin
    Mefst10-Nov-03 0:50
    Mefst10-Nov-03 0:50 
    GeneralGetting rid of the whitespace that isn't necessary when the scrollbar isn't visible. Pin
    Gemini_II29-Aug-03 3:15
    Gemini_II29-Aug-03 3:15 
    Generalread a txt file witch selected by a combobox Pin
    nicolasgib1-Aug-03 17:17
    nicolasgib1-Aug-03 17:17 
    QuestionHow to make List and Combo Box right aligned? Pin
    Dhirendra10-Jun-03 3:28
    Dhirendra10-Jun-03 3:28 
    AnswerRe: How to make List and Combo Box right aligned? Pin
    debeyao20-Jul-03 14:57
    debeyao20-Jul-03 14:57 
    GeneralRe: How to make List and Combo Box right aligned? Pin
    Member 218050228-Sep-05 23:30
    Member 218050228-Sep-05 23:30 
    GeneralRe: How to make List and Combo Box right aligned? Pin
    vcplusplus5-May-06 7:52
    vcplusplus5-May-06 7:52 
    QuestionWhy using SaveDC/RestoreDC? Pin
    LarryLeonard9-May-03 4:04
    LarryLeonard9-May-03 4:04 
    AnswerRe: Why using SaveDC/RestoreDC? Pin
    Chris Maunder9-May-03 4:24
    cofounderChris Maunder9-May-03 4:24 

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

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.