Webocreation

Monday, November 23, 2009

Using List Boxes

Using List Boxes

This section describes how to initialize and retrieve information from list boxes, and how to use list boxes in advanced ways.

The controls introduced in earlier sections of this chapter are very simple. They represent a single piece of information whose value you want to get or set. Interaction with these controls can be limited to DDX through a single dialog class data member.

Because the nature of list boxes is more complicated, it is often necessary to add a control variable to the dialog box class. This control variable allows easy initialization and enables you to call all the member functions of the list box class. ClassWizard creates this control variable for you. Because the list boxes must be preloaded with information, the CDialog::OnInitDialog function is often overridden. This section explains how to write code to use these complex controls in list boxes.

This section includes the following topics:

Initializing a List Box

When ClassWizard adds a variable to a dialog box class, the variable can be one of two types: a value member variable or a control member variable. With most of the simple controls — edit controls, check boxes, and radio buttons — you can use a value member variable.

When initializing a list box, deciding whether to use a value or control member variable is more complex and depends on what you want to do with the data. You need a value member variable so you can get an individual value back from the list box. The value member variable makes it easy to retrieve the string (or int) from the list box. You may also need a control member variable so that you can insert many data items into the list box. The solution is to add both types of variables, or in some cases, just a value member variable.

Note Initialization can be done without creating the control member variable. However, it is easier to use the control member variable.

The following example code is for a dialog box that contains a list box with the Sort property cleared. ClassWizard adds both an int (value member variable) and a control member variable to the dialog box class, which is named m_color and m_colorListBox. The effect in the dialog box class's header file is as follows.

class CColorListDlg : public CDialog
{
...
// Dialog Data
//{{AFX_DATA(CColorListDlg)
enum { IDD = IDD_PHRASE_COLOR2 };
CListBox m_colorListBox;
int m_color;
//}}AFX_DATA
...
};

OnInitDialog is the appropriate place to initialize list boxes and perform any other specialized processing. When you override this function, place the code where the comments indicate, and do not modify the AppWizard-generated code.

List boxes that are represented in the dialog box class by control member variables are initialized in the way shown in the following example code:

BOOL CColorListDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_colorListBox.AddString("Black");
m_colorListBox.AddString("Red");
m_colorListBox.AddString("Green");
m_colorListBox.AddString("Blue");
m_colorListBox.SetCurSel(0);
...
}

List boxes represented in the dialog class by only a value member variable are initialized in the way shown in the following example code:

CListBox * clb = (CListBox *)GetDlgItem(IDC_COLOR_LIST);
clb->AddString("Black");
clb->AddString("Red");
clb->AddString("Green");
clb->AddString("Blue");
clb->SetCurSel(0);

Setting the height of a list box is handled during initialization. To do this, define the number of items in the list box before it is displayed. The following code sets the height of a list box at run time.

// These are the steps needed to precisely set the
// height of the list box.
CRect rect;
int itemHeight;
m_colorListBox.GetClientRect(&rect);
m_colorListBox.MapWindowPoints(this, & rect);
itemHeight = m_colorListBox.GetItemHeight(0) + 1;
rect.bottom = rect.top + 4 * itemHeight;
m_colorListBox.MoveWindow(&rect);

Retrieving Information from a List Box

Once the value member variable is in place in the dialog class, DDX as performed in DoDataExchange places the user's selection into that variable. Use the variable as you would any other public data member of a class.

In the following example, the value member variable of the list box is an integer. This can be extracted very simply from the dialog class, where m_color is a public member that must then be converted to an RGB value for use by the document object:

if (IDOK == dlg.DoModal())
{
pDoc->SetPhrase(dlg.m_phrase);
pDoc->SetColor(IntToRgb(dlg.m_color));
Invalidate();
}

The function IntToRgb looks like the following code example:

COLORREF IntToRgb(int r)
{
switch(r)
{
case 1:
return RED;
case 2:
return GREEN;
case 3:
return BLUE;
default:
return BLACK;
}
}

Note If you clear the Sort option, the member variable can be an int corresponding to the index of the item in the list, or a CString for the selection.

For more information about list boxes, see "CListBox" in Visual C++ Help.

Sample Applications

Here are short descriptions of the sample applications related to this chapter. These sample applications are located in the folder \Samples\Ch09.

Sample application subfolder Description of application

\Modal Shows how to implement a modal dialog box.

\Tabbed Shows how to implement a modal tab dialog box with two property sheets.

Self-Check Questions

1. For which controls are groups especially important?

A. Radio buttons
B. Static text controls
C. Up-down (spin) controls
D. All controls

2. What results when you use ClassWizard to create a dialog member variable and bind it to a control?
A. A new class is automatically generated for the parent dialog box.
B. A new CControl-derived class is created and an instance of this class is embedded in the parent dialog class.
C. A new member variable is created in the parent dialog class.
D. ClassWizard generates no source code, but maintains this information in the project’s .clw file.

3. Which one of the following statements is true about the relationship of DDX and DDV?
A. DDX and DDV occur when the user clicks OK.
B. The developer can force DDX and DDV by calling CWnd::DoDataExchange.
C. The developer cannot extend DDX and DDV.
D. DDX and DDV are mutually exclusive; only one can be performed for each control.

No comments:

Post a Comment