Topic : Common Controls
Author : Unknown
Page : 1 Next >>
Go to page :

Common Controls

In this tutorial we will discuss some common controls that can be included in a dialog box. These controls include spin control, progress bar control, slider control, tree control, tab control, animate control and combo box. These controls can all be included in a dialog template as resources. Besides, all the controls have corresponding MFC classes that can be used to implement them.

In Developer Studio, Class Wizard has some features that can be used to add member variables and message handlers for the common controls. This simplifies the procedure of writing source code.

1 Spin Control

Spin control is a rectangular button with two arrows pointing to opposite directions (either vertically or horizontally), it is one of the most commonly used controls in a dialog box. Usually a spin is used together with another control, in most cases this control is an edit box (Though not common, this control can also be a button or a static control). By clicking on one of the arrows, the contents in the accompanying control will change accordingly indicating current position of the spin control.

The control used together with the spin control is called spin's Buddy Control. In MFC, it is very easy to use spin control along with edit box, they are specially designed to cooperate together.

Using Spin Control with Edit Box

By default, a spin control should be associated with an edit box. Usually this type of edit box contains a number indicating the current position of spin. If we make no modification, the range of this number will be from 0 to 100. If the spin's orientation is vertical, pressing the downward arrow will cause the number to increment. If the spin's orientation is horizontal, pressing the leftward arrow will have the same effect.

When adding a spin control resource, we must set several styles in order to make it work correctly. In the property page whose caption is "Spin properties", by clicking "Styles" tab, we will see all the customizable styles (Figure 1). Here, style "Auto buddy" will allow spin's buddy to be automatically selected (By enabling this style, we do not need to set spin's buddy within the program). If we check this selection, the window prior to the spin control in the Z order will be used as the spin's buddy window.

(Figure 1 omitted)

To let buddy window be automatically selected, we must first add resource for the buddy control then resource for the spin control. For example, if we want to use an edit box together with a spin control, we can add edit box resource first, then add spin control next. We can check controls' Z order by executing command Layout | Tab order (or pressing CTRL+D keys). The Z-order of the controls can be reordered by clicking them one by one according to the new sequence.

In the left-bottom corner of "Spin properties" property sheet, there is a combo box labeled "Alignment". This allows us to specify how the spin will be attached to its buddy window when being displayed. If we select "Unattatched" style, the spin and the buddy control will be separated. Usually we select either "Left" or "Right" style to attach the spin to the left or right side of the buddy control. In this case, the size and position of the spin control in the dialog template has no effect on its real size and position in the runtime, its layout will be decided according to the size and position of the buddy control.

Also, there is a "Set buddy integer" check box. If this style is set, the spin will automatically send out message to its buddy control (must be an edit box) and cause it to display a series of integers when the spin's position is changed. By default, the integer contained in the edit box will increment or decrement with a step of 1. If we want to customize this (For example, if we want to change the step or want to display floating point numbers), we should uncheck this style and set the buddy's text within the program.

Sample 1-1\CCtl demonstrates how to use spin control with edit control and set buddy automatically. The sample is a standard dialog based application generated by Application Wizard, with all default settings. The resource ID of the main dialog template is IDD_CCTL_DIALOG, which contains two spin controls and two edit boxes. Both spins have "Auto buddy" and "Set buddy integer" styles. Also, their alignment styles are set to "Right" (Figure 2).

(Figure 2 omitted)

Without adding a single line of code, we can compile the project and execute it. The spin controls and the edit controls will work together to let us select integers (Figure 3).

(Figure 3 omitted)

In MFC, spin control is implemented by class CSpinButtonCtrl. We need to call various member functions of this class in order to customize the properties of the spin control. In sample 1-2\CCtl, the control's buddy is set by calling function CSpinButtonCtrl::SetBuddy(...) instead of using automatic method. The best place to set a spin's buddy is in the dialog box's initialization stage. This corresponds to calling function CDialog::OnInitDialog().

Sample 1-2\CCtl is based on sample 1-1\CCtl. Here, style "Auto buddy" is removed for two spin controls. Also, some changes are nade to set the spin buddies manually.

There are two ways of accessing a specific spin: we can use a spin's ID to call function CWnd::GetDlgItem(...), which will return CWnd type pointer to the spin control; or we can add a CSpinButtonCtrl type variable for the spin control (through using Class Wizard). The following code fragment shows how the buddy of the two spin controls are set using the first method:

(Code omitted)

Since CWnd::GetDigItem(...) returns a CWnd type pointer, we need to first cast it to CSpinButtonCtrl type pointer in order to call any member function of class CSpinButtonCtrl. The only parameter that needs to be passed to function CSpinButtonCtrl::SetBuddy(...) is a CWnd type pointer to the buddy control, which can also be obtained by calling function CWnd::GetDlgItem(...).

Spin controls implemented in sample 1-2\CCtl behaves exactly the same with those implemented in sample 1-1\CCtl.

2 Customizing the Properties of Spin Control

We can customize a spin control's properties in function CDialog::OnInitDialog(). The following three functions are the most commonly used ones for doing customization:

(Table omitted)

Sample 2\CCtl is based on sample 1-1\CCtl. In this sample, the vertical spin is customized to display hexadecimal integers, whose range is set from 0x0 to 0xC8 (0 to 200), and its initial position is set to 0x64 (100). The horizontal spin still displays decimal integers, its range is from 50 to 0, and the initial position is 25. The following portion of function CCCtlDlg::OnInitDialog() shows the newly added code:

(Code omitted)

3 Displaying Text Strings in the Buddy Window

Sometimes we want the buddy to display text strings rather than numerical numbers. For example, we may prefer the text displayed in the buddy window to be "One", "Two", "Three"... rather than "1", "2", "3".... To customize this style, we could not use "Set buddy integer" style anymore. Instead, we need to write our own message handlers and set the buddy control's text by ourselves.

When the position of a spin has changed, the parent window of the spin control will receive a UDN_DELTAPOS message. From this message, we can get the current position of the spin control, along with the proposed change to the current position. Based on this information, we can decide what we should display in the buddy control window.

Sample 3\CCtl demonstrates how to display text strings in a buddy window. It is based on sample 2\CCtl, with a new spin control IDC_SPIN_STR and an edit box IDC_EDIT_STR added to the application. The edit control will display text strings "Zero", "One", "Two",..., "Nine" instead of integers. The buddy of spin IDC_SPIN_STR is set automatically.

The UDN_DELTAPOS message handler can be added through following steps: 1) Invoke Class Wizard, click "Messages Maps" tab. 2) Select "CCCtlDlg" class from "Class name" window, then highlight "IDC_SPIN_STR" in "Object IDs" window. 3) There will be two messages contained in "Messages" window, we need to highlight "UDN_DELTAPOS" and press "Add function" button. The newly added function will look like follows:

void CCCtlDlg::OnDeltaposSpinStr(NMHDR* pNMHDR, LRESULT* pResult)



*pResult = 0;


The first parameter here is a NMHDR type pointer. This is a structure that contains Windows( notification messages. A notification message is sent to the parent window of a common control to notify the changes on that control. It is used to handle events such as mouse left button clicking, left button double clicking, mouse right button clicking, and right button double clicking performed on a common control. Many types of common controls use this message to notify the parent window. For spin control, after receiving this message, we need to cast the pointer type from NMHDR to NM_UPDOWN. Here structure MN_UPDOWN is defined as follows:

typedef struct _NM_UPDOWN { nmud

NMHDR hdr; // notification message header

int iPos; // current position

int iDelta; // proposed change in position


In the structure, member iPos specifies the current position of the spin control, and iDelta indicates

Page : 1 Next >>