8.4.6 Scroll Bars

Scroll bars are predefined controls that can be positioned anywhere in a window. They allow a user to select a value from a continuous range of values. The scroll bar sends a notification message to its parent window whenever the user clicks the control by using the mouse or moves the scroll box (or “thumb”) by using the keyboard; this allows the parent window to process the messages so that it can determine the value selected by the user and position the scroll box appropriately.

To create a child-window scroll bar, use the SBS_HORZ or SBS_VERT style. You can create a scroll bar with any desired size. If you want the width (of a vertical scroll bar) or height (of a horizontal scroll bar) to match the size of a window scroll bar, you can use the appropriate system metrics, as shown in the following example:

hScrollBar = CreateWindow("Scrollbar", NULL,
    WS_CHILD | WS_VISIBLE | SBS_VERT,
    20, 20,
    GetSystemMetrics(SM_CXVSCROLL), 50,
    hWnd, IDSCROLLBAR, hinst, NULL);

The GetSystemMetrics function returns the current value for SM_CXVSCROLL, which is the width of a standard window scroll bar.

Scroll bars do not have a special set of notification messages. Instead, they send the same messages (WM_HSCROLL and WM_VSCROLL) sent by window scroll bars. The wParam parameter of these messages contains a value that indicates what kind of scrolling is being performed. Your application uses this information to determine how to position the scroll box and what that position means to your application.

Windows is capable of properly positioning the scroll box associated with a list box or edit control, based on the contents of the control. However, a scroll bar that is a child window represents a range of values known only to your application. As a result, your application must set the scrolling range for the scroll bar and must position the scroll box each time the user moves it.

The SetScrollRange function establishes the range of values that the scroll bar represents. For example, if your application has a scroll bar with which the user can select a day in a given month, you would call SetScrollRange to set the scroll bar range to the number of days in a particular month. The following example shows how your application could set the range for the month of January:

SetScrollRange(hScrollBar, SB_CTL, 1, 31, TRUE);

In this example, SB_CTL means the scroll bar is a separate control, not a control associated with a window. The third and fourth parameters specify the scroll bar range, and the fourth parameter is set to TRUE to direct Windows to redraw the scroll bar to reflect the new range.

Even if you have established the range of values that the scroll bar represents, Windows still cannot position the scroll box properly when the user moves it; your application must do this. Each time your application receives a WM_HSCROLL or WM_VSCROLL message for the scroll bar, it must check the wParam parameter of the message to determine how far the user moved the scroll box. Your application can then call the SetScrollPos function to position the scroll box. Also, if you allow the user (through your application) to change the value represented by the scroll box position without using the scroll bar (such as by typing in an edit control), your application must reposition the scroll box based on the new value.