Chapter 9

Progress Bar, Slider, and Spinner Controls


As a Windows user, you've long been accustomed to seeing controls like buttons, list boxes, menus, and edit boxes. As Windows developed, however, Microsoft noticed that applications developers routinely created other types of controls in their programs. These controls included things like toolbars, status bars, progress bars, tree views, and others. To make life easier for Windows programmers, when Microsoft created Windows 95 (and the latest version of Windows NT), it included these popular controls as part of the operating environment. Now, Windows programmers no longer need to create their own versions of these controls from scratch. In this chapter, you'll be introduced to several of Windows 95's common controls.

The Win95 Controls Application

Over the course of the next few chapters, you build a sample program called Win95 Controls App. You can find the program's executable file, as well as the complete source code, in the CHAP09 folder at this book's Web site. When you run the program, you see the window shown in Figure 9.1. As you can see, Win95 Controls App demonstrates five of the Windows 95 common controls: the progress bar, slider, spinner, list view, and tree view controls. In this chapter, you'll learn the basics of creating and using three of these controls.


FIG. 9.1

The Windows 95 Controls App demonstrates five of Windows 95's common controls.

To get going quickly, you'll start creating the Win95 Controls application using AppWizard. Then you'll learn how to use MFC to create and manipulate the Windows 95 controls demonstrated by the application. To build the basic Win95 Controls application, follow the steps given next.

ON THE WEB

http://www.quecorp.com/semfc The complete source code and executable file for this part of the Win95 application can be found in the CHAP09\Win95, Part 1 directory at this book's Web site.

  1. Choose Developer Studio's File, New command, and create a new AppWizard application called Win95, as shown in Figure 9.2.

    FIG. 9.2

    Create a new AppWizard project workspace.
  2. Choose the following options in the six MFC AppWizard pages. When the New Project Information dialog box appears, it should look like Figure 9.3.
  3. Step 1 Single document.
    Step 2 of 6 Use default options.
    Step 3 of 6 Use default options.
    Step 4 of 6 Turn off everything except 3D Controls.
    Step 5 of 6 Use default options.

    Step 6 of 6Use default classes.


  4. FIG. 9.3
    When you've created the project, the New Project Information dialog box should look like this.
  5. In the New Project Information dialog box, click the OK button. Developer Studio creates the new project's source code files.
  6. Click on the ResourceView tab to display the application's resources (see Figure 9.4).

    FIG. 9.4

    Click the ResourceView tab.
  7. Double-click Win95 Resources in the ResourceView window, double-click Dialog, and then double-click IDD_ABOUTBOX. The dialog box editor appears, as shown in Figure 9.5.

    FIG. 9.5

    When you click on a dialog box resource's ID, the dialog box editor opens.
  8. Use the editor to change the dialog box's title to About Win95 Controls App; to change the version line to Win95 Controls App, Version 1.0; and to add the line by Macmillan Computer Publishing to the dialog box below the copyright line, as shown in Figure 9.6.

    FIG. 9.6

    The finished dialog box should look like this.
  9. Double-click Menu in the ResourceView menu and then double-click IDR_MAINFRAME. The menu editor appears (see Figure 9.7).

    FIG. 9.7

    When you double-click a menu resource ID, the menu editor appears.
  10. Click the Edit menu (in the menu editor), and then press your keyboard's Delete key to remove the menu from the resource.
  11. Click the File menu and then delete all the menu items except Exit.
  12. Click the Help menu, and then double-click the About entry to bring up the Menu Items Properties dialog box. Change the About win95 menu item to &About Win95 Controls App .
  13. Double-click String Table in the ResourceView window, and then double-click the String Table resource. The string table editor appears (see Figure 9.8).

    FIG. 9.8

    When you double-click a string table resource, the string table editor appears.
  14. Double-click the IDR_MAINFRAME string in the string table. When the String Properties dialog box appears, change the first segment of the caption string from win95 to Win95 Controls App (see Figure 9.9). This is the string that appears as the application's title in the application's title bar.

    FIG. 9.9

    Change the application's title in the IDR_MAINFRAME string.
  15. Double-click Accelerator in the ResourceView window, and then double-click IDR_MAINFRAME. The accelerator editor appears (see Figure 9.10).

    FIG. 9.10

    When you click an accelerator resource, the accelerator editor appears.
  16. Use your keyboard's Delete key to delete all accelerators from the accelerator table. This prevents the user from accidentally selecting a hotkey for a command that the application does not support.
  17. Load the application's MAINFRM.CPP file and then add the following lines to the beginning of the PreCreateWindow() function:
       cs.cx = 480;
        cs.cy = 440;

These lines set the size of the application's main window.

You have now completed the first part of the Win95 Controls App. Compile and link the application by selecting the Build button in the toolbar; by selecting Developer Studio's Build, Build command; or by pressing F7. When you have the program compiled, you can run it if you like. However, all you'll see at this point is a blank window, as shown in Figure 9.11. In the following sections in this chapter, you'll add several Windows 95 common controls to the application, starting with the progress bar control. In the next chapter, you'll complete the application.


FIG. 9.11

This is the basic Win95 Controls App, before any controls have been added.

The Progress Bar Control

Probably the easiest to use of the new common controls is the progress bar, which is nothing more than a rectangle that fills in slowly with colored blocks. The more colored blocks filled in, the closer to complete a task is. When the progress bar is completely filled in, the task associated with the progress bar is also complete. You might use a progress bar to show the status of a sorting operation or to give the user visual feedback about a large file that's being loaded.

To add the progress bar to the Win95 Controls App application, follow these steps.

ON THE WEB

http://www.quecorp.com/semfc The complete source code and executable file for this part of the Win95 application can be found in the CHAP09\Win95, Part 2 directory at this book's Web site.

  1. Use ClassWizard to add the OnCreate() function to the CWin95View class, as shown in Figure 9.12.

    FIG. 9.12

    Here's how to use ClassWizard to add the OnCreate() function to the application's view class.
  2. Click the Edit Code button and then add the following line to OnCreate(), right after the TODO: Add your specialized creation code here comment:
    CreateProgressBar();
  3. Add the function shown in Listing 9.1 to the end of the WIN95VIEW.CPP file.

    Listing 9.1[em]LST09_01.CPP[md]The CreateProgressBar() Function

    void CWin95View::CreateProgressBar()
    {
        m_progressBar.Create(WS_CHILD | WS_VISIBLE | WS_BORDER,
            CRect(20, 40, 250, 80), this, 102);
        m_progressBar.SetRange(1, 100);
        m_progressBar.SetStep(10);
        m_progressBar.SetPos(50);
        m_timer = FALSE;
    }
  4. Add the following line to the OnDraw() function, right after the TODO: Add draw code for native data here comment:

    pDC->TextOut(20, 22, "Progress Bar Control");

  5. Use ClassWizard to add the OnLButtonDown() function to the view class, as shown in Figure 9.13.

    FIG. 9.13

    Here's how to use ClassWizard to add the OnLButtonDown() function to the application.
  6. Click the Edit Code button and then add the lines shown in Listing 9.2 to OnLButtonDown(), right after the TODO: Add your message handler code here and/or call default comment.

    Listing 9.2[em]LST09_02.CPP[md]Code for the OnLButtonDown() Function

        if (m_timer)
        {
            KillTimer(1);
            m_timer = FALSE;
        }
        else
        {
            SetTimer(1, 500, NULL);
            m_timer = TRUE;
        }
  7. Use ClassWizard to add the OnTimer() function to the view class, as shown in Figure 9.14.

    FIG. 9.14

    Here's how to use ClassWizard to add the OnTimer() function to the application.
  8. Click the Edit Code button and then add the following line to OnTimer(), right after the TODO: Add your message handler code here and/or call default comment:
    m_progressBar.StepIt();
  9. Use ClassWizard to add the OnDestroy() function to the view class, as shown in Figure 9.15.

    FIG. 9.15

    Here's how to use ClassWizard to add the OnDestroy() message response function to the application.
  10. Click the Edit Code button and then add the following line to OnDestroy(), right after the TODO: Add your message handler code here comment:

    KillTimer(1);

  11. Load the WIN95VIEW.H file and then add the following lines to the class's Attribute section, right after the line CWin95Doc* GetDocument():
    protected:
        CProgressCtrl m_progressBar;
        BOOL m_timer;
  12. Add the following line to the class's Implementation section, right after the protected keyword:

    void CreateProgressBar();

You have now completed the second part of the Win95 Controls App. Compile and link the application by selecting the Build button in the toolbar; by selecting Developer Studio's Build, Build command; or by pressing F7. When you run the application now, you see the window shown in Figure 9.16.


FIG. 9.16

The Win95 Controls App now sports a snazzy progress bar.

To see the progress bar in action, click anywhere in the background of Win95 Controls App's window. When you do, the progress bar starts filling with colored blocks. When the progress bar is completely filled, it starts over again. This continues until you click the window again or exit the program. Of course, in this program, the progress bar isn't tracking a real task in progress. It's simply responding to timer messages. However, the program still demonstrates how you might use a progress bar in your own applications.

Creating the Progress Bar

This might be an obvious statement, but before you can use a progress bar, you must create it. Often in an MFC program, the controls are created as part of a dialog box. However, Win95 Controls App displays its controls in the application's main window. It does this by creating controls in the view class's OnCreate() function, which responds to the WM_CREATE Windows message. The progress bar control is declared as a data member of the view class, like this:

protected:
    CProgressCtrl m_progressBar;

As you can see, the progress bar is an object of the MFC CProgressCtrl class.

To create the progress bar control, OnCreate() calls the local CreateProgressBar() member function, like this:

CreateProgressBar();

In CreateProgressBar() is where the fun begins. First, the function creates the progress bar control by calling the control's Create() function:

m_progressBar.Create(WS_CHILD | WS_VISIBLE | WS_BORDER,
    CRect(20, 40, 250, 80), this, 102);

This function's four arguments are the control's style flags, the control's size (as a CRect object), a pointer to the control's parent window, and the control's ID. (Usually, you declare a constant, such as IDC_PROGRESSBAR, to use as the control's ID. I used a hard-coded value to keep the code as simple as possible.) The style constants are the same constants you would use for creating any type of window (a control is really nothing more than a special kind of window, after all). In this case, you need at least WS_CHILD (which indicates that the control is a child window) and WS_VISIBLE (which ensures that the user can see the control). The WS_BORDER style is a nice addition, because it adds a dark border around the control, setting it off from the rest of the window.

Initializing the Progress Bar

As soon as the progress bar control is created, it must be initialized. The CProgressCtrl class features a number of member functions that enable you to initialize and manipulate the control. Those member functions and their descriptions are listed in Table 9.1.

Table 9.1 Member Functions of the CProgressCtrl Class

Function Description
Create() Creates the progress bar control
OffsetPos() Advances the control the given number of blocks
SetPos() Sets the control's current value
SetRange() Sets the control's minimum and maximum values
SetStep() Sets the value by which the control advances
StepIt() Advances the control by one step unit

To initialize the control, you merely call the CProgressCtrl object's appropriate member functions, which Win95 Controls App does like this:

m_progressBar.SetRange(1, 100);
m_progressBar.SetStep(10);
m_progressBar.SetPos(50);

The call to SetRange() determines the values represented by the progress bar. The two arguments are the minimum and maximum values. So, after the preceding call to SetRange(), if the progress bar is set to 1, it displays no colored blocks; in contrast, setting the control's position to 100 fills the control with colored blocks.

Next, the CreateProgressBar() function calls SetStep(), which determines how far the progress bar advances with each increment. The larger this value, the faster the progress bar fills with colored blocks. Because the range and the step rate are related, a control with a range of 1[nd]10 and a step rate of 1 works almost identically to a control with a range of 1[nd]100 and a step rate of 10.

When the Win95 Controls App starts, the progress bar is already half filled with colored blocks. (This is purely for aesthetic reasons. Usually a progress bar begins its life empty.) This is because of the call to SetPos() with the value of 50, which is the midpoint of the control's range.

Manipulating the Progress Bar

In Win95 Controls App, the progress bar starts counting forward when you click in the window's background. This is because the program responds to the mouse click by starting a timer that sends WM_TIMER messages to the program twice a second. In the view class's OnTimer() function, the program makes the following function call:

m_progressBar.StepIt();

The StepIt() function increments the progress bar control's value by the step rate, causing new blocks to be displayed in the control as the control's value setting counts upward. When the control reaches its maximum, it automatically starts over.

Notice that there are no CProgressCtrl member functions that control the size or number of blocks that will fit into the control. This attribute is controlled indirectly by the size of the control.

The Slider Control

Many times in a program, the user might have enter a value that lies within a specific range. For this sort of task, you'd use MFC's CSliderCtrl class to create a slider (sometimes called a trackbar) control. For example, suppose you need the user to enter a percentage that your program needs to calculate another value. In that case, you'd want the user to enter only values in the range from 0 to 100. Other values would be invalid and could cause problems in your program if such invalid values were not carefully trapped.

Using the slider control, you can force the user to enter a value in the specified range. Although the user can accidentally enter a wrong value (a value that doesn't accomplish what the user wants to do), he or she can't enter an invalid value (one that brings your program crashing down like a stone wall in an earthquake).

In the case of a percentage, you'd create a slider control with a minimum value of 0 and a maximum value of 100. Moreover, to make the control easier to position, you'd want to place tick marks at each setting that's a multiple of 10, giving 11 tick marks in all (including the one at 0). Win95 Controls App creates exactly this type of slider. The following steps show you how to add the control to Win95 Controls App.

ON THE WEB

http://www.quecorp.com/semfc The complete source code and executable file for this part of the Win95 application can be found in the CHAP09\Win95, Part 3 directory at this book's Web site.

  1. Load the WIN95VIEW.CPP file and then add the following line to the OnDraw() member function, right after the line pDC->TextOut(20, 22, "Progress Bar Control") that you placed there previously:

    pDC->TextOut(270, 22, "Slider Control:");

  2. Add the following line to the OnCreate() function, right after the line CreateProgressBar() that you placed there previously:

    CreateSlider();

  3. Add the function shown in Listing 9.3 to the end of the WIN95VIEW.CPP file.

    Listing 9.3 LST09_03.CPP The CreateSlider() Function

    void CWin95View::CreateSlider()
    {
        m_slider.Create(WS_CHILD | WS_VISIBLE | WS_BORDER |
            TBS_AUTOTICKS | TBS_BOTH | TBS_HORZ,
            CRect(270, 40, 450, 80), this, 101);
        m_slider.SetRange(0, 100, TRUE);
        m_slider.SetTicFreq(10);
        m_slider.SetLineSize(1);
        m_slider.SetPageSize(10);
    }
  4. Use ClassWizard to add the OnHScroll() function to the view class, as shown in Figure 9.17.

    FIG. 9.17

    Here's how to use ClassWizard to add the OnHScroll() function to the program.
  5. Click the Edit Code button and then add the lines shown in Listing 9.4 to OnHScroll(), right after the // TODO: Add your message handler code here and/or call default comment.

    Listing 9.4 LST09_04.CPP Code for the OnHScroll() Function

        CSliderCtrl* slider = (CSliderCtrl*)pScrollBar;
        int position = slider->GetPos();
        char s[10];
        wsprintf(s, "%d   ", position);
        CClientDC clientDC(this);
        clientDC.TextOut(390, 22, s);
  6. Load the view class's header file (WIN95VIEW.H) and then add the following line to the class's Attributes section, right after the line BOOL m_timer that you placed there previously:

    CSliderCtrl m_slider;

  7. Add the following line to the class's Implementation section, right after the line void CreateProgressBar() that you placed there previously:

    void CreateSlider();

You have now completed the third part of the Win95 Controls App. Compile and link the application by selecting the Build button in the toolbar; by selecting Developer Studio's Build, Build command; or by pressing F7. When you run the application now, you see the window shown in Figure 9.18.


FIG. 9.18

The Win95 Controls App now has a slider control, as well as a progress bar control.

To see the slider work, click on the slider's slot. When you do, the slider moves forward or backward, and the selected value appears to the right of the control's caption. As soon as the slider has the focus, you can also control it with your keyboard's Up Arrow and Down Arrow keys, as well as with the Page Up and Page Down keys. You can also drag the slider with your mouse to whatever position you like.

Creating the Slider

In the Win95 Controls App application, the slider is created in the CreateSlider() local member function, which, like CreateProgressBar(), the program calls from the view class's OnCreate() function. In CreateSlider(), the program first creates the slider control by calling its Create() member function, like this:

m_slider.Create(WS_CHILD | WS_VISIBLE | WS_BORDER |
    TBS_AUTOTICKS | TBS_BOTH | TBS_HORZ,
    CRect(270, 40, 450, 80), this, 101);

This function's four arguments are the control's style flags, the control's size (as a CRect object), a pointer to the control's parent window, and the control's ID. The style constants include the same constants that you would use for creating any type of window, with the addition of special styles used with sliders. Table 9.2 lists these special styles.

Table 9.2 Slider Styles

Style Description
TBS_AUTOTICKS Enables the slider to automatically draw its tick marks
TBS_BOTH Draws tick marks on both slides of the slider
TBS_BOTTOM Draws tick marks on the bottom of a horizontal slider
TBS_ENABLESELRANGE Enables a slider to display a subrange of values
TBS_HORZ Draws the slider horizontally
TBS_LEFT Draws tick marks on the left side of a vertical slider
TBS_NOTICKS Draws a slider with no tick marks
TBS_RIGHT Draws tick marks on the right side of a vertical slider
TBS_TOP Draws tick marks on the top of a horizontal slider
TBS_VERT Draws a vertical slider

Initializing the Slider

As soon as the slider control is created, it must be initialized. The CSliderCtrl class features many member functions that enable you to initialize and manipulate the control. Those member functions and their descriptions are listed in Table 9.3.

Table 9.3 Member Functions of the CSliderCtrl Class

Function Description
ClearSel() Clears a selection from the control
ClearTics() Clears tick marks from the control
Create() Creates a slider control
GetChannelRect() Gets the size of the control's slider
GetLineSize() Gets the control's line size
GetNumTics() Gets the number of tick marks
GetPageSize() Gets the control's page size
GetPos() Gets the control's position
GetRange() Gets the control's minimum and maximum values
GetRangeMax() Gets the control's maximum value
GetRangeMin() Gets the control's minimum value
GetSelection() Gets the current range selection
GetThumbRect() Gets the size of the control's thumb
GetTic() Gets the position of a tick mark
GetTicArray() Gets all the control's tick positions
GetTicPos() Gets the client coordinates of a tick mark
SetLineSize() Sets the control's line size
SetPageSize() Sets the control's page size
SetPos() Sets the control's position
SetRange() Sets the control's minimum and maximum values
SetRangeMax() Sets the control's maximum value
SetRangeMin() Sets the control's minimum value
SetSelection() Sets a selected subrange in the control
SetTic() Sets the position of a tick mark
SetTicFreq() Sets the control's tick frequency
VerifyPos() Determines whether the control's position is valid

Usually, when you create a slider control, you'll want to set the control's range and tick frequency. If the user is going to use the control from his or her keyboard, you also need to set the control's line and page size. In the Win95 Controls App application, the program initializes the slider as shown in Listing 9.5.

Listing 9.5 LST09_05.CPP Initializing the Slider Control

m_trackbar.SetRange(0, 100, TRUE);
m_trackbar.SetTicFreq(10);
m_trackbar.SetLineSize(1);
m_trackbar.SetPageSize(10);

The call to SetRange() sets the slider's minimum and maximum values to 0 and 100, respectively. The arguments are the minimum value, the maximum value, and a Boolean value indicating whether the slider should redraw itself after setting the range. Next, the call to SetTicFreq() ensures that there will be a tick mark at each interval of 10. (Without this function call, the slider would have a tick mark for each possible setting, 101 in all.) Finally, the call to SetLineSize() determines how much the slider moves when the user presses his or her Up Arrow or Down Arrow keys, and the call to SetPageSize() determines how much the slider moves when the user presses the Page Up or Page Down keys.

Manipulating the Slider

When you get down to it, a slider is really a special scroll bar control. As such, when the user moves the slider, the control generates WM_HSCROLL messages, which Win95 Controls App captures in its view class's OnHScroll() member function, shown in Listing 9.6.

Listing 9.6 LST09_06.CPP Responding to a Slider Contro

void CWin95View::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
    // TODO: Add your message handler code here and/or call default
    
    CSliderCtrl* slider = (CSliderCtrl*)pScrollBar;
    int position = slider->GetPos();
    char s[10];
    wsprintf(s, "%d   ", position);
    CClientDC clientDC(this);
    clientDC.TextOut(390, 22, s);
    CView::OnHScroll(nSBCode, nPos, pScrollBar);
}

OnHScroll()'s fourth parameter is a pointer to the scroll object that generated the WM_HSCROLL message. The preceding function first casts this pointer to the CSliderCtrl pointer. It then gets the current position of the slider by calling the CSliderCtrl member function GetPos(). As soon as the program has the slider's position, it converts the integer to a string and displays that string in the window.

The Spinner Control

The slider control isn't the only way you can get a value in a predetermined range from the user. If you don't care about using the slider for visual feedback, you can use a spinner control, which is little more than a couple of arrows that the user clicks to raise or lower the control's setting. If the slider control is a scroller with only a bar and a thumb, then a spinner control is the leftover arrow buttons. Follow the steps that come next to add a spinner control to Win95 Controls App.

ON THE WEB

http://www.quecorp.com/semfc The complete source code and executable file for this part of the Win95 application can be found in the CHAP09\Win95, Part 4 directory at this book's Web site.

  1. Load the WIN95VIEW.CPP file and then add the following line to the OnDraw() member function, right after the line pDC->TextOut(270, 22, "Slider Control:"), which you placed there previously:

    pDC->TextOut(20, 102, "Spinner Control");

  2. Add the following line to the OnCreate() function, right after the line CreateSlider(), which you placed there previously:

    CreateSpinner();

  3. Add the function shown in Listing 9.7 to the end of the WIN95VIEW.CPP file.

    Listing 9.7 LST09_07.CPP The CreateSpinner() Function

    void CWin95View::CreateSpinner()
    {
        m_buddyEdit.Create(WS_CHILD | WS_VISIBLE | WS_BORDER,
            CRect(50, 120, 110, 160), this, 103);
        m_spinner.Create(WS_CHILD | WS_VISIBLE | WS_BORDER |
            UDS_ALIGNRIGHT | UDS_SETBUDDYINT | UDS_ARROWKEYS,
            CRect(0, 0, 0, 0), this, 104);
        m_spinner.SetBuddy(&m_buddyEdit);
        m_spinner.SetRange(1, 100);
        m_spinner.SetPos(50);
    }
  4. Load the view class's header file (WIN95VIEW.H) and then add the following lines to the class's Attributes section, right after the line CSliderCtrl m_slider that you placed there previously:
    CSpinButtonCtrl m_spinner;
        CEdit m_buddyEdit;
  5. Add the following line to the class's Implementation section, right after the line void CreateSlider() that you placed there previously:

    void CreateSpinner();

You have now completed the fourth part of the Win95 Controls App. Compile and link the application by selecting the Build button in the toolbar; by selecting Developer Studio's Build, Build command; or by pressing F7. When you run the application now, you see the window shown in Figure 9.19.


FIG. 9.19

This version of Win95 Controls App adds a spinner to the other controls.

In the Win95 Controls App application, you can change the setting of the spinner control by clicking either of its arrows. When you do, the value in the attached edit box changes, indicating the spinner control's current setting. As soon as the control has the focus, you can also change its value by pressing your keyboard's Up Arrow and Down Arrow keys.

Creating the Spinner Control

In the Win95 Controls App application, the spinner control is created in the CreateSpinner() local member function, which the program calls from the view class's OnCreate() function. In CreateSpinner(), the program creates the spinner control by first creating the associated buddy control to which the spinner control communicates its current value. In this case, as is typical, the buddy control is an edit box, which is created by calling the CEdit class's Create() member function:

m_buddyEdit.Create(WS_CHILD | WS_VISIBLE | WS_BORDER,
    CRect(50, 120, 110, 160), this, 103);

This function's four arguments are the control's style flags, the control's size, a pointer to the control's parent window, and the control's ID. As you might remember from the control declarations, m_buddyEdit is an object of the CEdit class.

Now that the program has created the buddy control, it can create the spinner control in much the same way, by calling the object's Create() member function, like this:

m_spinner.Create(WS_CHILD | WS_VISIBLE | WS_BORDER |
    UDS_ALIGNRIGHT | UDS_SETBUDDYINT | UDS_ARROWKEYS,
    CRect(0, 0, 0, 0), this, 104);

As you can guess by now, this function's four arguments are the control's style flags, the control's size, a pointer to the control's parent window, and the control's ID. As with most controls, the style constants include the same constants that you would use for creating any type of window. However, the CSpinButtonCtrl class, of which m_spinner is an object, defines special styles to be used with spinner controls. Table 9.4 lists these special styles.

Table 9.4 Spinner Styles

Style Description
UDS_ALIGNLEFT Places the spinner control on the left edge of the buddy control
UDS_ALIGNRIGHT Places the spinner control on the right edge of the buddy control
UDS_ARROWKEYS Enables the user to change the control's values using the keyboard's Up Arrow and Down Arrow keys
UDS_AUTOBUDDY Makes the previous window the buddy control
UDS_HORZ Creates a horizontal spinner control
UDS_NOTHOUSANDS Eliminates separators between each set of three digits
UDS_SETBUDDYINT Displays the control's value in the buddy control
UDS_WRAP Causes the control's value to wrap around to its minimum when the maximum is reached and vice versa

Initializing the Spinner Control

As soon as the spinner control is created, it must be initialized. The CSpinButtonCtrl class features member functions that enable you to initialize and manipulate the control. Those member functions and their descriptions are listed in Table 9.5.

Table 9.5 CSpinButtonCtrl Member Functions

Function Description
Create() Creates the spinner control
GetAccel() Gets the control's speed
GetBase() Gets the control's numerical base
GetBuddy() Gets a pointer to the control's buddy control
GetPos() Gets the control's position
GetRange() Gets the control's minimum and maximum values
SetAccel() Sets the control's speed
SetBase() Sets the control's numerical base (10 for decimal, 16 for hex)
SetBuddy() Sets the control's buddy control
SetPos() Sets the control's position
SetRange() Sets the control's minimum and maximum values

After creating a spinner control, you'll usually want to set the control's buddy, range, and position. In the Win95 Controls App application, the program initializes the control like this:

m_spinner.SetBuddy(&m_buddyEdit);
m_spinner.SetRange(1, 100);
m_spinner.SetPos(50);

Here, the spinner control's buddy is set to the edit box that was first created in CreateSpinner(). Then the program calls SetRange() and SetPos() to give the control its starting range and position, respectively. Thanks to the UDS_SETBUDDYINT flag passed to Create() and the call to the control's SetBuddy() member function, Win95 Controls App needs to do nothing else to have the control's value appear on the screen. The control handles its buddy automatically.