MFC combo Box (ComboBox) Control toggle drop-down style

Source: Internet
Author: User

Because of the needs of the subject needs to do MFC serial Port program, read the interface style of Baidu download serial assistant, found this design is very good

The baud rate combo box gives only 5 selectable values, and the 6th option is custom, which is entered manually.

In fact, the BaudRate optional value of the DCB structure is too much, to make the drop-down box will be very long, this approach is to choose the most common options, do not need to manually enter the user, and do not need to be in a long list to choose.

As you can see from the Properties box of VS, there are 3 styles of combo box controls, which is the ability to switch from drop list to dropdown when you click the Custom option.

From MSDN, you can see that the corresponding macros are cbs_dropdownlist and Cbs_dropdown, respectively.

Reference: Https://msdn.microsoft.com/en-us/library/12h9x0ch.aspx

So I originally wanted to use the Cwnd::modify () method to modify the style, but failed, the reason for the search, the drop-down style can only be determined at the time of creation, cannot be changed after creation.

It is therefore reasonable to manually create an identical control and then use the CWnd::ShowWindow () method to automatically switch.

-----------------------------------------------------------------------------------Split Line----------------------------------- -----------------------------------------------

The following is a detailed implementation method starting from 0, a new MFC-based dialog box Program (Set dialog Class Ccombotestdlg), manually drag a ComboBox control up. Set type and ID

Add an associated variable of type CComboBox to the control in the Class Wizard, or add it manually as follows:

1. In ComboTestDlg.h, define the public variable in the Cxxxdlg class

CComboBox M_cmbold;

2. In ComboTestDlg.cpp, Cxxxdlg: Add a row of associated statements:D the Odataexchange () method

DDX_Control (PDX, Idc_combo_old, m_cmbold);

Now define the public variable m_cmbnew in the Ccombotestdlg class, but do not modify the DoDataExchange () method, as you will manually create the drop-down box

CComboBox m_cmbnew;

Modify the Ccombotestdlg::oninitdialog () method to add the following code

    //gets the location of the original drop-down boxCRect rect; M_cmbold.getwindowrect (&rect);  This->screentoclient (&rect); //gets the font of the original drop-down boxcfont* Pfont =M_cmbold.getfont (); //Gets the style of the original drop- down box (change the Drop list to dropdown)DWORD dwstyle =M_cmbold.getstyle (); Dwstyle^=cbs_dropdownlist; Dwstyle|=Cbs_dropdown; //Create a new drop-down box that is identicalM_cmbnew.create (Dwstyle, Rect, This, idc_combo_new); //set the same fontM_cmbnew.setfont (Pfont); //Hide New drop-down box by defaultM_cmbnew.showwindow (Sw_hide);

There are two points to note in the above code (that is, the pit I stepped on ...). )

1. Coordinate conversion screentoclient, because GetWindowRect gets the position relative to the entire parent control (including the title bar), and create requires a position relative to the client area (excluding the title bar), so it needs to be converted;

2. GetFont and SetFont set the font, without this step, the font created by the Create drop-down box may not be the same as the automatically created drop-down box font.

PS: Macro idc_combo_new need to be added manually in resource.h, be careful not to be the same as other macros to avoid conflicts.

That's all you need to do to switch, assuming my drop-down box contains 4 items: CPP, Java, Python, custom, click Custom to switch to manual input mode.

Add a global variable in ComboTestDlg.cpp (the syntax for list initialization is c++11) so that it can be accessed directly by subscript

#include <vector>std::vector<CString> g_strtext = {_t ("cpp"), _t ( " Java "), _t ("python"), _t ("custom")};

Continue adding initialization code after the code that you just added in Ccombotestdlg::oninitdialog ()

 for 0; I < g_strtext.size (); i++)    {    //  c++11 can be used in <type_traits> std::extent<decltype (text);:: Value gets the text array size         m_cmbold.addstring (G_strtext[i]);        M_cmbnew.addstring (G_strtext[i]);    }    M_cmbold.setcursel (0//  Select first item by default ("CPP")

Then add response events to each of the 2 controls, and for the default control M_cmbold, you can add a method with the Class wizard

Actually did these things:

1. In ComboTestDlg.h, add the declaration of the member function in the Ccombotestdlg class

void Oncbnselchangecomboold ();

2. In ComboTestDlg.cpp, add between message map macro Begin_message_map (Ccombotestdlg, CDialog) and End_message_map ()

On_cbn_selchange (Idc_combo_old, &ccombotestdlg::oncbnselchangecomboold)

3. In CComboTestDlg.cpp, add a specific definition of the member function

void Ccombotestdlg::oncbnselchangecomboold () {    //  TODO: Add control notification handler code here }

After knowing these points, divert, add the corresponding code in the same position as the above 3 steps, and if you select an existing item, the original drop-down box will be displayed.

void Oncbnselchangecombonew ();
On_cbn_selchange (Idc_combo_new, &ccombotestdlg::oncbnselchangecombonew)
void ccombotestdlg::oncbnselchangecombonew () {}

When you enter custom data, you need to respond to the carriage return message, and Use the Class Wizard (for example, click Add Function) to give Ccombotestdlg overloaded virtual function PreTranslateMessage ()

This step actually does these things:

1. In ComboTestDlg.h, add a declaration of a virtual function in the Ccombotestdlg class

Virtual BOOL PreTranslateMessage (msg* pMsg);

2. In ComboTestDlg.cpp, add the definition of the virtual function

BOOL Ccombotestdlg::P retranslatemessage (msg* pMsg) {    //  TODO: Add private code here and/or call base class    return CDialog::P retranslatemessage (PMSG);}

Now that the framework has been set up, just add the specific switching logic in the added functions

void Ccombotestdlg::oncbnselchangecomboold () {    CString text;    M_cmbold.getwindowtext (text);     if (Text = = _t ("custom"))    {    //  switch to Manual edit drop-down box         M_cmbold.showwindow (sw_hide);        M_cmbnew.showwindow (sw_show);        M_cmbnew.setfocus ();    }     Else     {        MessageBox (text);    }}
voidccombotestdlg::oncbnselchangecombonew () {CString text;    M_cmbnew.getwindowtext (text); if(Text = = _t ("Custom"))    {    //re-enterM_cmbnew.setwindowtext (_t ("")); }    Else    {    //switch to the original drop-down boxM_cmbnew.showwindow (sw_hide);        M_cmbold.showwindow (Sw_show); M_cmbold.setcursel (M_cmbold.findstring (0, text));    MessageBox (text); }}
BOOL Ccombotestdlg::P retranslatemessage (msg*PMSG) {    //TODO: Add private code here and/or call base class    if(Pmsg->message = =wm_keydown) {        if(Pmsg->wparam = = Vk_return)//Enter        {            if(M_cmbnew.getfocus ()) {//adding control information to the listCString text;                M_cmbnew.getwindowtext (text); intNselect = m_cmbnew.findstring (0, text); if(Nselect = =-1)                {    //Add control information to the drop-down box if it does not exist in the list itemg_strtext.push_back (text);                    M_cmbold.addstring (text);                M_cmbnew.addstring (text); }                Else                {    //Displays the original drop-down box and navigates to the list item if it already existsM_cmbnew.showwindow (sw_hide);                    M_cmbold.showwindow (Sw_show);                M_cmbold.setcursel (Nselect);            } MessageBox (text); }        }    }    returnCDialog::P retranslatemessage (PMSG);}

This completes the function, can be based on the actual needs of some code encapsulation, after all, MFC API encapsulation is very shallow.

Features are described below

1. The initial dialog box displays a combo box of the drop list type.

2. When a list item other than custom is selected, a pop-up window displays the text of the list item.

3. When custom is selected, it enters edit mode and the drop-down box becomes the dropdown type.

4. Press ENTER when finished editing, and if the text is already in the list item, a pop-up window displays the text and the combo box changes back to the drop list type, otherwise the input text is added to the end of the list item.

5. When the combo box is a dropdown type, if a list item other than custom is selected, the combo box is then drop list type.

MFC combo Box (ComboBox) Control toggle drop-down style

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.