MFC Combo Boxes

 

Combo Box Fundamentals

 

Description

 

Combo Box Properties

 

Dropping Down

By default, a newly added combo box is of drop down type. The kind of display is controlled by the Type combo box of the Properties window and its default value is Dropdown. This is programmatically equivalent to adding the CBS_DROPDOWN style.

 

A drop down combo box allows the user to type a new value if the desired string is not in the list. To do this, the user can click the edit side of the control and start typing. If the user types a string that is longer than the width of the edit box part, the control would cause the computer to start making a beep sound, indicating that the user cannot type beyond the allocated length. If you want the user to be able to type a long string, check or set to True the Auto HScroll property. If you are programmatically creating the control, you can do this by adding the CBS_AUTOHSCROLL style.

When the list of items is too long for the reserved rectangular area of the list side to display, the control gets automatically equipped with a vertical scroll bar. This is because its Vertical Scroll check box or property is automatically checked or set to True. If you allow or add this style, if the list is not too long and can be accommodated by the rectangle, no scroll bar would be displayed. If the list is too long and you set this property, then a vertical scroll bar would automatically appear on the control. If you insist on displaying a vertical scroll bar even if the rectangle is long enough to display all items, check the Disable No Scroll check box or set it to True. In this case, if the rectangle can accommodate all items, a disabled vertical scroll bar would appear on the control. y either checking the (or setting it to True) or creating the combo box with the WS_HSCROLL window style. Based on this convenience, unless you have a strong reason to do otherwise, you should always allow the vertical scroll bar.

 

Combo Box List Display

If you do not want the user to be able to type a new string, set the Type property to Drop List or create the control with a CBS_DROPDOWNLIST style. With this type, whether the user clicks the edit part or the arrow button, the list would drop. If the user finds the desired value and clicks it, the list retracts and the new selection displays in the edit part of the control. If the user does not find the desired item in the list, he or she can click the edit box or the arrow button. In this case, the selection would not be changed. If you want the list part of the combo box to always display, like the list box control, set the Type property to Simple or create it with the CBS_SIMPLE style.

 

When the Owner Draws the List

The combo boxes we have mentioned so far are created by their control, in which case the combo boxes are responsible for creating and updating their list. You can create a combo box that relies on its owner for all related operations. Such a combo box is referred to as owner draw. When an owner is responsible for drawing the items of a combo box, it can set the value of each item as it sees fit. For example, different items of the same list can use different fonts. They can display different types of items and they can even draw anything on their line. The ability to feature a combo box as owner draw or not is specified using the Owner Draw combo box of the Properties window. Its default value is No. To create an owner draw combo box where all items have the same height, set this property to the Fixed value. This is equivalent to adding the CBS_OWNERDRAWFIXED style to a dynamic combo box. On the other hand, if you want items to have different heights, set the Owner Draw value to Variable or create he control with a CBS_OWNERDRAWVARIABLE style.

 

Operations on a Combo Box

 

Combo Box Creation

A combo box is based on the CComboBox class. Therefore, if you want to dynamically create this control, declare a variable or a pointer to CComboBox using its default constructor. To initialize the control, call its Create() method. Here is an example:

BOOL CExerciseDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    SetIcon(m_hIcon, TRUE); // Set big icon
    SetIcon(m_hIcon, FALSE); // Set small icon

    // TODO: Add extra initialization here
    CComboBox *Majors = new CComboBox;

    Majors->Create(WS_CHILD | WS_VISIBLE |
    WS_VSCROLL | CBS_DROPDOWNLIST,
    CRect(10, 50, 100, 150), this, 0x1448);

    return TRUE; // return TRUE unless you set the focus to a control
}

 

 

List Creation

After creating the control, probably the next action to take consists of creating its items. To add a string to a combo box, you can call the CComboBox::AddString() method that uses the same syntax as the CListBox::AddString() member function. Here is an example:

BOOL CExerciseDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    SetIcon(m_hIcon, TRUE); // Set big icon
    SetIcon(m_hIcon, FALSE); // Set small icon

    // TODO: Add extra initialization here
    CComboBox *Majors = new CComboBox;

    Majors->Create(WS_CHILD | WS_VISIBLE |
    WS_VSCROLL | CBS_DROPDOWNLIST,
    CRect(10, 50, 100, 150), this, 0x1448);

    Majors->AddString("Accounting");
    Majors->AddString("Art Education");
    Majors->AddString("Finance");
    Majors->AddString("Biology");

    return TRUE; // return TRUE unless you set the focus to a control
}
 

The Index of the Selected Item

Consider the following dialog box:

When a user clicks an item in the combo box to select it, you have two options to find out what the user clicked. If you want to know the index of the item that the user clicked, you can call the GetCurSel() method of the CComboBox class. Here is an example:

void CExoDlg1Dlg::OnBnClickedSelect()
{
	// TODO: Add your control notification handler code here
	m_Categories.GetCurSel();
}

When this method is called, if no item is selected in the combo box, the method returns a CB_ERR error. Therefore, before performing any operation, it would be wise to find out the returned value of this method, especially to find out if it produced a CB_ERR error. This can be done as follows:

void CExoDlg1Dlg::OnBnClickedSelect()
{
	// TODO: Add your control notification handler code here
	int index = m_Categories.GetCurSel();

	if( index != CB_ERR )
	{
		// Do Something With the Selected Item
	}
}
 

The Selected String

Besides, or instead of, the index of the selected item, you may be more interested in the string that the user selected in the combo box, especially if the combo box is not "Owner Draw". To get this string, you can call the GetLBText() method of the combo box. It comes in two versions whose syntaxes are:

int GetLBText(int nIndex, LPTSTR lpszText) const;
void GetLBText(int nIndex, CString& rString) const;

The first argument is the index of the item selected. The second argument is the string in which the selected item will be stored. As you can see, it is passed by reference. Here is an example:

void CExoDlg1Dlg::OnBnClickedSelect()
{
	// TODO: Add your control notification handler code here
	CString strSelected;
	int index = m_Categories.GetCurSel();

	if( index != CB_ERR )
	{
		this->m_Categories.GetLBText(index, strSelected);
		this->m_Selected = strSelected;
	}

	UpdateData(FALSE);
}
 

Combo Box Messages and Events

When you add or create a combo box, an amount of space is allocated and during the lifetime of your application, the combo box uses some memory to processing its assignments. If at one time there is not enough memory for the processing, the combo box sends an ON_CBN_ERRSPACE message.

Like any control, for the user to use the combo box, it must first have focus. This can be done by the user clicking its edit part, its list part (for a Simple combo box) or its down pointing arrow (for a drop type combo box). When the combo box receives focus, its sends the ON_CBN_SETFOCUS message.

Once the control has focus, if the user clicks or had clicked the edit side of the combo box that already had a selected item, if the user starts typing, which would modify the string of the item that was already selected, the combo box would send the ON_CBN_EDITCHANGE message (remember that the user can change the string only if the combo box was not created as Drop List). If the user finishes typing or changing the string, just before the altered string is validated, the combo box sends the ON_CBN_EDITUPDATE message.

To select an item from a drop type combo box, the user usually clicks the down pointing arrow button to display the control’s list. When the user clicks that button, just before the list displays, the control sends the ON_CBN_DROPDOWN message. After this click and this message, the list part of a drop combo box displays and the user must make a decision:

  • If the user finds the desired item in the list, he or she must let the combo box know. This is done by highlighting it. To do this, the user can either click (with the mouse) or press the arrow keys (on the keyboard) to indicate his or her choice. When this highlighting occurs, the combo box sends the ON_CBN_SELCHANGE message, notifying the application that the combo box’ selection may be changed soon
  • Once the user has found the desired item and has possibly highlighted it, if using the mouse, he or she can click to select it. If using the keyboard, after locating the item, the user can press Enter. Clicking the desired item or pressing Enter on the highlighted string means that the user has made a definite selection. This causes the control to send an ON_CBN_SELENDOK message, notifying the application that the user has made his or her decision.
  • If the user did not find the desired item, he or she may want to dismiss the combo box without making a selection. There are three main ways the user can invalidate a selection. If the user clicks another control or another application, if the list was displaying, it would retract and not selection would be made, event if the user had already highlighted an item. If the user clicks either the edit box part of the combo box for a Drop List type or the down pointing button, the selection is dismissed and if the list of a drop type was displaying, it would retract. If the user presses Esc, the selection would be dismissed.
    Any of these actions causes the selection to be dismissed or the user to cancel the selection action. This causes the combo box to send an ON_CBN_SELENDCANCEL message.

Once the user has clicked an item or pressed Enter to validate a selection, if the combo box was created not as Simple, the list part of the controls retracts to hide itself. At this time, the combo box sends an ON_CBN_CLOSEUP message.

If the user finishes using the combo box and moves to another control, the combo box sends an ON_CBN_KILLFOCUS message, notifying the application that it (the combo box) has lost focus.

 

Related Articles

Time Sheet

Download


Copyright © 2003 FunctionX, Inc.