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

be one of our sliders, we call function CSliderCtrl::GetPos() to retrieve its current position, and output the slider ID along with its current position to the debug window. In order to see the activities of the sliders, the application must be executed in the debug mode within Developer Studio.

6 List Box

List box is a control that contains a list of objects such as file names and strings that can be selected by mouse clicking. When we create a list box, there are many styles that can be customized (Figure 6). For example, if we check "Horizontal scroll" style, the list box will automatically implement a horizontal scroll bar if any of its string is too long to be fully displayed in the list window. If we check "Vertical scroll" style, the list box will add a vertical scroll if the vertical size of the list box is not big enough for displaying all items. Some other important styles that a list box can have are "Multi-column", "Sort", "Selection" and "Owner draw".

(Figure 6 omitted)

Usually a list box has a single column. If we set "Multi-column" style, the list box can have multiple horizontal columns. Originally the list box will be empty, when we start to add new items, they will be added to the first column (column 0). If the first column is full, instead of creating a vertical scroll bar and continue to add items to this column, the list box will create a new column and begin to fill it. This step will be repeated until all items are filled into the list box. Here, the width of each column is always the same. Because a multiple-column list box will always try to extend horizontally rather than vertically, it is important to let this type of list box have a horizontal scroll bar.

The "Sort" style will be set by default. If we remain this style, all the strings contained in the list box will be alphabetically sorted. For the "Selection" styles, we have several choices. A "Single" style list box allows only one item in the list box to be selected at any time. A "Multiple" style list box allows several items to be selected at the same time. If we enable this style, the user can use SHIFT and CTRL keys together to select several items. Besides these two, there is also an "Extended" style. If we enable it, the items can be selected or deselected through mouse dragging. Finally, list box with "Owner draw" style allows us to implement it so that the list box can contain non-string items. In this case, we need to provide custom list box interface.

Sample 6\CCtl demonstrates basic styles of list box. It is a dialog-based application created by Application Wizard. There are three list boxes implemented in the application, whose IDs are IDC_LIST, IDC_LIST_MULCOL and IDC_LIST_DIR respectively. The styles of IDC_LIST are all set to default, it is a single selection, single column, sorted list box with a vertical scroll bar. The styles of IDC_LIST_MULCOL are multiple-column, multiple-selection, it does not support sort. The styles of IDC_LIST are also set to default, except that it supports "extended selection" style. To access these list boxes, three CListCtrl type member variables m_listBox, m_listMCBox and m_listDir are declared in class CCtlDlg through using Class Wizard (Figure 7).

(Figure 7 omitted)

Unless we initialize the content of these list boxes, they will be empty at the beginning. Like other common controls, initialization procedure of list box is usually implemented in function CDialog:: OnInitDlalog(). To fill a list box with strings, we need to call function CListBox::AddString(...). Strings will be added starting from item 0, 1, 2... and so on (If a list box has a sorted style, the string will be sorted automatically). Besides this function, we can also use function Clistbox::InsertString(...) to insert a new string before certain item instead of adding it to the end of the list. The following code fragment shows how the content of list boxes IDC_LIST and IDC_MULCOL are filled:

(Code omitted)

If we do not specify the column width for a multiple-column list box, the default column width will be used. We may set this width by calling function CListBox::SetColumnWidth(...). In the sample 6\CCtl, the column width of IDC_LIST_MULCOL is set 50 (pixels) as follows:

BOOL CCtlDlg::OnInitDialog()



m_listMCBox.AddString("Item 20");




All the columns will have the same width. For list box IDC_LIST_DIR, instead of filling each entry with a string, we can let it display a list of directories and file names for the current working directory. This can be implemented by calling function CListBox::Dir(...), which has the following format:

int CListBox::Dir(UINT attr, LPCTSTR lpszWildCard);

Here, the first parameter specifies file attributes, which can be used to specify what type of files can be added to the list. The following is a list of some attributes that are commonly used:

(Table omitted)

The second parameter is a string, which can be used to set file filter. In the sample, this function is called as follows:

BOOL CCtlDlg::OnInitDialog()



m_listDir.Dir(0x10, "*.*");

return TRUE;


Here, value 0x10 is passed to the first parameter of function CListBox::Dir(...) to let normal files along with directories be listed, also, we use "*.*" wildcards to allow all types of names to be added to the list.

When testing the sample application, we can use mouse along with SHIFT and CONTROL keys to select items. Also, we can drag mouse over items to test extended selection style.

7 Handling List Box Messages

Like other common controls, list box has its own messages that are related to mouse or keyboard activities.

Trapping Double Clicking Message

In the previous sample, it may be helpful to trap mouse double clicking message for list box IDC_LIST_DIR. When the user double clicks a directory, we can change the contents of the list box, fill it with the file and directory names contained under the directory being clicked. This feature is implemented in sample 7\CCtl, which is based on sample 6\CCtl.

The double clicking message of a list box is LBN_DBLCLK. We can easily add handler for this message through using Class Wizard: after invoking the Class Wizard, by clicking "Message maps" tab and selecting class "CCtlDlg", three IDs of the list boxes will be listed in "Object IDs" window. We can highlight "IDC_LIST_DIR", then select "LBN_DBCLK" message from "Messages" window, and press button "Add function". If we accept the default function name, a new function CtlDlg::OnDblclkListDir() will be added to the application.

Retrieving the Contents of an Item

After receiving the double clicking message, we need to obtain the string contained in the item that was clicked. For a single selection list box, the current selected item can be retrieved by calling function CListBox::GetCurSel() (After being double clicked, the item must become currently selected). This function will return a zero based index indicating which item is currently being selected. Then we can call function CListBox::GetText(...) to retrieve the string contained in the item. Since list IDC_LIST_DIR is a multiple-selection list box, retrieving text from the selected items is a little different. In this case, first function CListBox::GetSelCount() must be called to retrieve the number of items that are currently being selected. According to this value, we must allocate enough buffers for storing indices of the selected items. Then we can call function CListBox::GetSelItems(...) and pass the buffer's address to it for receiving indices of all the selected items. For each index, we can call CListBox::GetText(...) to retrieve its string.

After a double clicking, one and only one item in the list box will be selected. In this case, we can skip the first step because CListBox::GetSelCount() will surely return 1. If a list item represents directory, a pair of square brackets "[]" will be added to the directory name. So we can judge if the item being double clicked contains a file name or a directory name by examining if the string starts and ends with square brackets. If we allow drive names to be displayed, the items containing drive names will be displayed in the format of "[-X-]", where X represents the drive name. In our samples, this situation is not considered).

The following is the implementation of function CCtlDlg::OnDblclkListDir(). This function examines the clicked item. If the item contains a directory name, we need to update the contents of the list box (File and directory names under the directory being clicked will be retrieved and filled into the list box):

(Code omitted)

First function CListCtrl::GetSelItems(...) is called to retrieve the currently selected item. The result is stored to a local variable nIndex. Then text string of the selected item is obtained by calling function CListCtrl::GetText(...). If the string starts with "[", it is a directory, and we extract the directory name by calling function CString::Mid(...). Then contents of the list box are cleared by calling function CListCtrl::ResetContent(). Next, the current working directory is changed by calling function _chdir(...). Finally, the list box is filled with the new directory and file names by calling function CListCtrl::Dir(...). Since function _chdir(...) is not an MFC function, we need to include "direct.h" header file in

Page : << Previous 3  Next >>