Topic : Common Controls
Author : Unknown
Page : << Previous 4  Next >>
Go to page :

order to use it.


Besides directory changing, another new feature is also implemented in the sample application: we can use mouse to highlight any item contained in the other two list boxes. When the dialog box is closed, a message box will pop up displaying all the items that are currently being selected.

Before a window is destroyed, it will receive a WM_DESTROY message, so we can handle this message to do clean up work. In our case, this is the best place to retrieve the final state of the list boxes. Please note that we can not do this in the destructor of class CCtlDlg, because at that time the dialog box window and all its child window have already been destroyed. If we try to access them, it will cause the application to malfunction.

Message handler WM_DESTROY can be added by using Class Wizard through following steps: 1) Click "Message maps" tab and choose "CCtlDlg" class in window "Class name". 2) Highlight "CCtlDlg" in window "Object IDs". 3) In "Messages" window, find "WM_DESTROY" message and click "Add function" button. After the above steps, a new function CCtlDlg::OnDestroy() will be added to the application.

We will retrieve all the text strings of the selected items for three list boxes and display them in a message box. For list box IDC_LIST_BOX this is easy, because it allows only single selection. We can call function CListBox::GetCurSel() to obtain the index of the selected item and call CListBox::GetText(...) to retrieve the text:

(Code omitted)

Function CListBox::GetCurSel() will return value LB_ERR if nothing is being currently selected or the list box has a multiple-selection style. If there is a selected item, we use CString type variable szStrList to retrieve the text of that item.

For list box IDC_LIST_MULCOL and IDC_LIST_DIR, things become a little complicated become both of them allow multiple-selection. We need to first find out how many items are being selected, then allocate enough buffers for storing the indices of the selected items, and use a loop to retrieve the text of each item. Each time a new string is obtained, it is appended to the end of szStrList. The following code fragment shows how the text of all the selected items is retrieved for list box IDC_LIST_MULCOL:

(Code omitted)

In this function, first the number of selected items is retrieved by calling function CListBox::GetSelCount(), and the retrieved value is saved to variable nSelSize. If the size is not zero, we allocate an integer type array with size of nSelSize. Then by calling function CListBox::GetSelItems(...), we fill this buffer with the indices of selected items. Next, a loop is used to retrieve the text of each item. The procedure of retrieving selected text for list box IDC_LIST_DIR is the same.

8 Combo Box

Combo box is another type of common control that allows the user to select one object from a list. While a list box allows multiple selections, a combo box allows only single selection at any time. A combo box is made up of two other controls: an edit box and a list box. There are three types of combo boxes: 1) Simple combo box: the list box is placed below the edit box, and is displayed all the time; the edit box displays the currently selected item in the list box. 2) Drop down combo box: the list box is hidden most of the time; when the user clicks the drop-down arrow button located at the right corner of the edit box, the list box is shown and can be used to select an item. In both 1) and 2), the edit box can be used to input a string. 3) Drop list combo box: it is the same with drop down combo box, except that its edit box cannot be used to input string.

Using a combo box is more or less the same with that of a list box. We must first create combo box resources in the dialog template, set appropriate styles, then in the dialog's initialization stage (in function CDialog::OnInitDialog()), initialize the combo box. We can add message handlers to trap mouse or keyboard related events for combo box. Two most important messages for combo boxes are CBN_CLOSEUP and CBN_SELCHANGE. The first message indicates that the user has clicked the drop-down arrow button, made a selection from the list box, and the drop down list is about to be closed. The second message indicates that the user has selected a new item.

In MFC, combo box is supported by class CComboBox. Like CListBox, class CComboBox has a function CComboBox::AddString(...) which can be used to initialize the contents of its list box. Besides this, we can also initialize the contents of a list box when designing dialog template. In the property sheet whose caption is "Combo Box Properties", by clicking "Data" tab, we will have a multiple-line edit box that can be used to input initial data for combo box. We can use CTRL+RETURN keys to begin a new line (Figure 8).

(Figure 8 omitted)

Class CComboBox has two functions that allow us to change the contents contained in the list box dynamically: CComboBox::InsertString(...) and CComboBox:: DeleteString(...).

When designing drop-down combo box, we must set its vertical size, otherwise it will be set to the default value zero. In this case, there will be no space for the list box to be dropped down when the user clicks drop down button. To set this size, we can click the drop-down button in the dialog template. After doing this, a resizable tracker will appear. The initial size of a combo box can be adjusted by dragging the tracker's border (Figure 9).

(Figure 9 omitted)

Implementing Combo Boxes

Sample 8\CCtl demonstrates the basics of combo box. It is a standard dialog-based application generated by Application Wizard. Three different combo boxes are implemented in the sample, whose IDs are IDC_COMBO_SIMPLE, IDC_COMBO_DROPDOWN and IDC_COMBO_DROPLIST respectively. For these combo boxes, IDC_COMBO_SIMPLE is a "Simple" type, its items are initialized to "Item 1", "Item 2"... "Item 4" when designing the dialog template; IDC_COMBO_DROPDOWN is a "Drop down" type, and no initialization is done in the resource; IDC_COMBO_DROPLIST is a "Drop list" type, its contents are also initialized as "Item 1", "Item 2"... "Item 4" like IDC_COMBO_SIMPLE. All other styles are set as default, this will let all three combo boxes have vertical scroll bars automatically, and their items be sorted alphabetically.

Three static text controls IDC_STATIC_SIMPLE, IDC_STATIC_DROPDOWN and IDC_STATIC_DROPLIST are added below each combo box. We will use them to display the current selection of the corresponding combo box dynamically.

Three CComboBox type member variables, m_cbSimple, m_cbDropDown and m_cbDropList, are declared in class CCCtlDlg. They will be used to access the combo boxes This can be implemented through using Class Wizard as follows: 1) Invoke Class Wizard, click "Member variables" tab, select "CCCtlDlg" from window "Class name". 2) Highlight the ID of the combo box (IDC_COMBO_SIMPLE, IDC_COMBO_DROPDOWN or IDC_COMBO_DROPLIST), press "Add variable" button. 3) Select "Control" category and input the variable name.

In function CCCtlDlg::OnInitDialog(), the contents of combo box IDC_COMBO_DROPDOWN are initialized through calling function CComboBox::AddString(...):

(Code omitted)


We need to implement message handlers for CBN_CLOSEUP or CBN_SELCHANGE in order to respond to mouse's events. For combo box IDC_COMBO_DROPDOWN and IDC_COMBO_DROPLIST, we know that the selection is changed if we receive message CBN_CLOSEUP. For combo box IDC_COMBO_SIMPLE, we need to use CBN_SELCHANGE because the list box will not close after a new selection is made.

Message handlers can be easily added through using Class Wizard as follows: 1) Invoke Class Wizard, click "Message maps" tab and select "CCCtlDlg" from window "Class name". 2) Highlight the appropriate combo box ID in window "Object IDs". 3) In window "Messages", highlight the appropriate message (CBN_CLOSEUP for IDC_COMBO_DROPDOWN and IDC_COMBO_DROPLIST, CBN_SELCHANGE for IDC_COMBO_SIMPLE). 3) Click button "Add function" and confirm the member function name.

These functions will be called when the user makes a new selection from the list box of a combo box. We can retrieve the index of the current selection of a combo box by calling function CComboBox:: GetCurSel(), and further retrieve the text of that item by calling function CComboBox::GetLBText(...). At last we can call function CWnd::SetWindowText(...) to display the updated content of the selected item in one of the static text controls. The implementations of three message handlers are almost the same. The following is one of them:

(Code omitted)

First index of the current selection is retrieved and stored in variable nSel. Then we check if the returned value is CB_ERR. This is possible if there is nothing being currently selected. If the returned value is a valid index, we call function CComboBox::GetLBText(...) to retrieve the text string and store it in CString type variable szStr. Finally function CWnd::GetDlgItem(...) is called to obtain the pointer to the static text window, and CWnd::SetWindowText(...) is called to update its contents.

9 Trapping RETURN key strokes for the Combo Box

Problem & Workaround

One feature we may want to add to the combo boxes is to let the user dynamically add new items through using their edit boxes. We can let the user input a string into

Page : << Previous 4  Next >>