Jump to content

PMGuide - Scroll-Bar Controls

From EDM2
Revision as of 04:27, 6 May 2025 by Martini (talk | contribs) (Created page with "{{IBM-Reprint}} {{PMGuide}} Scroll bars are control windows that convert mouse and keyboard input into integers; they are used by an application to scroll the contents of a client window. This chapter describes how to create and use scroll bars in PM applications. === About Scroll Bars === A scroll bar has three main parts: the bar, its arrows, and a slider. The arrows are located at each end of the scroll bar. The left scroll arrow, on the left side of a horizontal sc...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation

Presentation Manager Programming Guide and Reference
  1. How to Use this Book
  2. Device Functions
  3. Direct Manipulation Functions
  4. Dynamic Data Formatting Functions
  5. Hooks and Procedures
  6. Profile Functions
  7. Spooler Functions
  8. Window Functions
  9. Message Processing
  10. Data Types
  11. Errors
  12. Atom Tables
  13. Button Controls
  14. Clipboards
  15. Combination Box
  16. Container Controls
  17. Control Windows
  18. Cursors
  19. Dialog Windows
  20. Direct Manipulation
  21. Drawing in Windows
  22. Dynamic Data Exchange
  23. Entry-Field Controls
  24. File Dialog Controls
  25. Font Dialog Controls
  26. Frame Windows
  27. Hooks
  28. Initialization Files
  29. Keyboard Accelerators
  30. List-Box Controls
  31. Menus
  32. Messages and Message Queues
  33. Multiple-Line Entry Field Controls
  34. Mouse and Keyboard Input
  35. Mouse Pointers and Icons
  36. Notebook Controls
  37. Painting and Drawing
  38. Presentation Parameters
  39. Resource Files
  40. Scroll-Bar Controls
  41. Slider Controls
  42. Spin Button Controls
  43. Static Controls
  44. Title-Bar Controls
  45. Value Set Controls
  46. Windows
  47. Window Classes
  48. Window Procedures
  49. Window Timers
  50. Appendices
  51. Notices
  52. Glossary

Scroll bars are control windows that convert mouse and keyboard input into integers; they are used by an application to scroll the contents of a client window. This chapter describes how to create and use scroll bars in PM applications.

About Scroll Bars

A scroll bar has three main parts: the bar, its arrows, and a slider. The arrows are located at each end of the scroll bar. The left scroll arrow, on the left side of a horizontal scroll bar, enables the user to scroll to the left in a document. The right scroll arrow lets the user scroll to the right. On a vertical scroll bar, the upper scroll arrow enables the user to scroll upward in the document; the lower scroll arrow, downward. The slider, which lies between the two scroll arrows, reflects the current value of the scroll bar. Scroll bars monitor the slider and send notification messages to the owner window when the slider position changes as a result of mouse or keyboard input. Although, typically, scroll bars are used in frame windows, an application can use stand-alone scroll bars of any size or shape, at any position, in a window of almost any class. Scroll bars can be used as parts of other control windows; for example, a list box uses a scroll bar to enable the user to view items when the list box is too small to display all the items.

Scroll-Bar Creation

An application can include a scroll bar in a standard frame window by specifying the FCF_HORZSCROLL or FCF_VERTSCROLL flag in the WinCreateStdWindow function. To create a scroll bar in another type of window, an application can specify the predefined (preregistered) window class WC_SCROLLBAR in the WinCreateWindow function or in the CONTROL statement in a resource file. Although most applications specify an owner window when creating a scroll bar, an owner is not required. If an application does not specify an owner, the scroll bar does not send notification messages.

Scroll-Bar Styles

A scroll bar has styles that determine what it looks like and how it responds to input. Styles are specified in the WinCreateWindow function or the CONTROL statement. A scroll-bar can have the following styles:

Style            Meaning
------------------------------------------------------------------------
SBS_AUTOTRACK    Causes the entire slider to track the movement of the mouse pointer
                 when the user scrolls the window. Without this style, only an
                 outlined image of the slider tracks the movement of the mouse
                 pointer, and the slider jumps to the new location when the user
                 releases the mouse button.
------------------------------------------------------------------------
SBS_HORZ         Creates a horizontal scroll bar.
------------------------------------------------------------------------
SBS_THUMBSIZE    Used to calculate the size of the scroll-bar slider from the
                 SBCDATA passed to WinCreateWindow.
------------------------------------------------------------------------
SBS_VERT         Creates a vertical scroll bar.
------------------------------------------------------------------------
Scroll-Bar Range and Position

Every scroll bar has a range and a slider position. The range specifies the minimum and maximum values for the slider position. As the user moves the slider in a scroll bar, the scroll bar reports the slider position as an integer in this range. If the slider position is the minimum value, the slider is at the top of a vertical scroll bar or at the left end of a horizontal scroll bar. If the slider position is the maximum value, the slider is at the bottom or right end of the vertical or horizontal scroll bar, respectively. An application can adjust the range to convenient integers by using SBM_SETSCROLLBAR or WM_SETWINDOWPARAMS, or by using the SBCDATA structure during creation of the scroll bar. This enables you to easily translate the slider position into a value that corresponds to the data being scrolled. For example, an application attempting to display 100 lines of text (numbered 0 to 99) in a window that can show only 20 lines at a time could set the vertical scroll-bar range from 0-99, permitting any line to be the top line, and requiring blank lines to fill the viewing area when there are not sufficient lines of information to fill the area (lines 80-99). More likely, the range would be set to 0-79, so that only the first 80 lines could be the top line; this guarantees that there would always be 20 lines of text to fill the window. The current settings can be obtained using SBM_QUERYRANGE or WM_QUERYWINDOWPARAMS. To establish a useful relationship between the scroll-bar range and the data, an application must adjust the range whenever the data or the size of the window changes. This means the application should adjust the range as part of processing WM_SIZE messages. An application must move the slider in a scroll bar. Although the user requests scrolling in a scroll bar, the scroll bar does not update the slider position. Instead, it passes the request to the owner window, which scrolls the data and updates the slider position using the SBM_SETPOS message. The application controls the slider movement and can move the slider in the increments best suited for the data being scrolled. An application can retrieve the current slider position of a scroll bar by sending the SBM_QUERYPOS message to the scroll bar. If a scroll bar is a descendant of a frame window, its position relative to its parent can change when the position of the frame window changes. Frame windows draw scroll bars relative to the upper-left corner of the frame window (rather than the lower-left corner). The frame window can adjust the y coordinate of the scroll-bar position, which would be desirable if the scroll bar is a child of the frame window, but would be undesirable if the scroll bar is not a child window.

Scroll-Bar Slider Size

The slider can be displayed either as a square (the default), or as a portion of the scroll bar if SBCDATA and the SBS_THUMBSIZE style are specified at creation. Displaying the slider as a proportional rectangle permits the size of the slider to be proportional to the amount of data being viewed in the visible range. The size is set based on the visible range and the number of values in the range. As an example, where the viewing area is 20 items and the range is 100, the slider size would be 20% of the potential slider area. Note that there is no direct connection between the scroll bar range and the range value used to set the slider size. It is possible to set the scroll-bar range from 0-99, and base the slider size on a viewing area of 500 and a range of 1000. This will set the scroll-bar to have 100 positions and will display a slider that is half the size of the scroll bar. The slider size can be set using SBM_SETTHUMBSIZE or WM_SETWINDOWPARAMS, and obtained using WM_QUERYWINDOWPARAMS.

Scroll-Bar Notification Messages

A scroll bar sends notification messages to its owner whenever the user clicks the scroll bar. WM_VSCROLL and WM_HSCROLL are the notification messages for vertical and horizontal scroll bars, respectively. If the scroll bar is a frame control window, the frame window passes the message to its client window. Each notification message includes the scroll-bar identifier, scroll-bar command code corresponding to the action of the user, and, in some cases, the position of the slider. If an application creates a scroll bar as part of a frame control window, the scroll-bar identifier is the predefined constant FID_VERTSCROLL or FID_HORZSCROLL. Otherwise, it is the identifier given in the WinCreateWindow function. The scroll-bar command codes specify the action the user has taken. Operating system user-interface guidelines recommend certain responses for each action. Following is a list of the command codes; for each code, the user action is specified, followed by the application's response. In each case, a scrolling unit, appropriate for the given data, must be defined by the application. For example, for scrolling text vertically, the typical unit is a line.

Command Code        Description
------------------------------------------------------------------------
SB_LINEUP           Indicates that the user clicked the top scroll arrow. Decrement
                    the slider position by one, and scroll toward the top of the data
                    by one unit.
------------------------------------------------------------------------
SB_LINEDOWN         Indicates that the user clicked the bottom scroll arrow. Increment
                    the slider position by one, and scroll toward the bottom of the
                    data by one unit.
------------------------------------------------------------------------
SB_LINELEFT         Indicates that the user clicked the left scroll arrow. Decrement
                    the slider position by one, and scroll toward the left end of the
                    data by one unit.
------------------------------------------------------------------------
SB_LINERIGHT        Indicates that the user clicked the right scroll arrow. Increment
                    the slider position by one, and scroll toward the right end of the
                    data by one unit.
------------------------------------------------------------------------
SB_PAGEUP           Indicates that the user clicked the scroll-bar background above
                    the slider. Decrement the slider position by the number of data
                    units in the window, and scroll toward the top of the data by the
                    same number of units.
------------------------------------------------------------------------
SB_PAGEDOWN         Indicates that the user clicked the scroll-bar background below
                    the slider. Increment the slider position by the number of data
                    units in the window, and scroll toward the bottom of the data by
                    the same number of units.
------------------------------------------------------------------------
SB_PAGELEFT         Indicates that the user clicked the scroll-bar background to the
                    left of the slider. Decrement the slider position by the number of
                    data units in the window, and scroll toward the left end of the
                    data by the same number of units.
------------------------------------------------------------------------
SB_PAGERIGHT        Indicates that the user clicked the scroll-bar background to the
                    right of the slider. Increment the slider position by the number
                    of data units in the window, and scroll toward the right end of
                    the data by the same number of units.
------------------------------------------------------------------------
SB_SLIDERTRACK      Indicates that the user is dragging the slider. Applications that
                    draw data quickly can set the slider to the position given in the
                    message, and scroll the data by the same number of units the
                    slider has moved. Applications that cannot draw data quickly
                    should wait for the SB_SLIDERPOSITION code before moving the
                    slider and scrolling the data.
------------------------------------------------------------------------
SB_SLIDERPOSITION   Indicates that the user released the slider after dragging it. Set
                    the slider to the position given in the message, and scroll the
                    data by the same number of units the slider was moved.
------------------------------------------------------------------------
SB_ENDSCROLL        Indicates that the user released the mouse after holding it on an
                    arrow or in the scroll-bar background. No response is necessary.
------------------------------------------------------------------------

If the command code is SB_SLIDERTRACK or SB_SLIDERPOSITION, indicating that the user is moving the scroll-bar slider, the notification message also contains the current position of the slider. The owner window can send a message to the scroll bar to read or reset the current value and range of the scroll bar. To reflect any changes in the state of the scroll bar, the owner window also can adjust the data the scroll bar controls. An application can use the WinEnableWindow function to disable a scroll bar. A disabled scroll bar ignores the actions of the user, sending out no notification messages when the user tries to manipulate it. If an application has no data to scroll, or if all data fits in the client window, the application should disable the scroll bar.

Scroll Bars and the Keyboard

When a scroll bar has the keyboard focus, it generates notification messages for the following keys:

Keys        Response
------------------------------------------------------------------------
UP          SB_LINEUP or SB_LINELEFT
------------------------------------------------------------------------
LEFT        SB_LINEUP or SB_LINELEFT
------------------------------------------------------------------------
DOWN        SB_LINEDOWN or SB_LINERIGHT
------------------------------------------------------------------------
RIGHT       SB_LINEDOWN or SB_LINERIGHT
------------------------------------------------------------------------
PGUP        SB_PAGEUP or SB_PAGELEFT
------------------------------------------------------------------------
PGDN        SB_PAGEDOWN or SB_PAGERIGHT
------------------------------------------------------------------------

If an application uses scroll bars to scroll data but does not give the scroll bar the input focus, the window with the focus must process keyboard input. The window can generate scroll-bar notification messages or carry out the indicated scrolling. The following table shows the responses to keys that a window must process:

Key             Response
------------------------------------------------------------------------
UP              SB_LINEUP
------------------------------------------------------------------------
DOWN            SB_LINEDOWN
------------------------------------------------------------------------
PGUP            SB_PAGEUP
------------------------------------------------------------------------
PGDN            SB_PAGEDOWN
------------------------------------------------------------------------
CTRL+HOME       SB_SLIDERTRACK, with the slider set to the minimum position
------------------------------------------------------------------------
CTRL+END        SB_SLIDERTRACK, with the slider set to the maximum position
------------------------------------------------------------------------
LEFT            SB_LINELEFT
------------------------------------------------------------------------
RIGHT           SB_LINERIGHT
------------------------------------------------------------------------
CTRL+PGUP       SB_PAGELEFT
------------------------------------------------------------------------
CTRL+PGDN       SB_PAGERIGHT
------------------------------------------------------------------------
HOME            SB_SLIDERTRACK, with the slider set to the minimum position
------------------------------------------------------------------------
END             SB_SLIDERTRACK, with the slider set to the maximum position
------------------------------------------------------------------------

For vertical scroll bars that are part of list boxes, the following table shows the responses to keys:

Key             Command
------------------------------------------------------------------------
CTRL+UP         SB_SLIDERTRACK, with the slider set to the minimum position
------------------------------------------------------------------------
CTRL+DOWN       SB_SLIDERTRACK, with the slider set to the maximum position
------------------------------------------------------------------------
F7              SB_PAGEUP
------------------------------------------------------------------------
F8              SB_PAGEDOWN
------------------------------------------------------------------------

Using Scroll Bars

This section explains how to perform the following tasks: - Create scroll bars - Retrieve a scroll-bar handle - Initialize, adjust, and read the scroll-bar range and position

Creating Scroll Bars

When creating a frame window, you can add scroll bars by specifying the FCF_HORZSCROLL flag, FCF_VERTSCROLL flag, or both flags in the WinCreateStdWindow function. This adds horizontal, vertical, or both (as specified) scroll bars to the frame window. The frame window owns the scroll bars and passes notification messages from the scroll bars to the client window. The following code fragment adds scroll bars to a frame window:

/* Set flags for a main window with scroll bars. */
ULONG ulFrameControlFlags = FCF_STANDARD | FCF_HORZSCROLL | FCF_VERTSCROLL;

/* Create the window. */
hwndFrame = WinCreateStdWindow(HWND_DESKTOP,
    WS_VISIBLE,
    &ulFrameControlFlags,
    szClientClass,
    szFrameTitle,
    0,
    (HMODULE) NULL,
    0,
    &hwndClient);

Scroll bars created this way have the window identifier FID_HORZSCROLL or FID_VERTSCROLL. To determine the size and position of the scroll bars, the frame window uses the standard size specified by the system values SV_CXVSCROLL and SV_CYHSCROLL. The position always is defined by the right and bottom edges of the frame window. Another way to create scroll bars is using the WinCreateWindow function. This method is most commonly used for stand-alone scroll bars. Creating scroll bars this way lets you set the size and position of the scroll bars. You also can specify which window should receive notification messages. The following code fragment creates a stand-alone scroll bar:

#define ID_SCROLL_BAR 1

HWND hwndScroll, hwndClient;
hwndScroll = WinCreateWindow(
    hwndClient,                      /* Scroll-bar parent window       */
    WC_SCROLLBAR,                    /* Preregistered scroll-bar class */
    (PSZ) NULL,                      /* No window title                */
    SBS_VERT | WS_VISIBLE,           /* Vertical style and visible     */
    10, 10,                          /* Position & Size                */
    20, 100,                         /* Size                           */
    hwndClient,                      /* Owner                          */
    HWND_TOP,                        /* Z-order position               */
    ID_SCROLL_BAR,                   /* Scroll-bar identifier          */
    NULL,                            /* No class-specific data         */
    NULL);                           /* No presentation parameters     */

Retrieving a Scroll-Bar Handle

If you use the WinCreateStdWindow function to create a scroll bar as a child of the frame window, you must be able to retrieve the scroll-bar handle. One way to do this is to use the WinWindowFromID function, the frame-window handle, and a predefined identifier (such as FID_HORZSCROLL or FID_VERTSCROLL), as shown in the following code fragment:

HWND hwndFrame, hwndHorzScroll, hwndVertScroll;

hwndHorzScroll = WinWindowFromID(hwndFrame, FID_HORZSCROLL);
hwndVertScroll = WinWindowFromID(hwndFrame, FID_VERTSCROLL);

If the standard frame window includes a client window, you can use that handle to access the scroll bars. The idea is to get the frame-window handle first; then, the scroll-bar handle:

HWND hwndScroll, hwndClient;

/* Get a handle to the horizontal scroll bar. */
hwndScroll = WinWindowFromID(
    WinQueryWindow(hwndClient, QW_PARENT),
    FID_HORZSCROLL);

Using the Scroll-Bar Range and Position

You can initialize the current value and range of a scroll bar to non-default values by sending the SBCDATA structure with class-specific data for a call to WinCreateWindow:

#define ID_SCROLL_BAR 1

SBCDATA sbcd;
HWND hwndScroll, hwndClient;

/* Set up scroll-bar control data. */
sbcd.posFirst = 200;
sbcd.posLast  = 400;
sbcd.posThumb = 300;

/* Create the scroll bar. */
hwndScroll = WinCreateWindow(hwndClient,
    WC_SCROLLBAR,
    (PSZ) NULL,
    SBS_VERT | WS_VISIBLE,
    10, 10,
    20, 100,
    hwndClient,
    HWND_TOP,
    ID_SCROLL_BAR,
    &sbcd,                     /* Class-specific data  */
    NULL);

You can adjust a scroll-bar value and range by sending it an SBM_SETSCROLLBAR message:

/* Set the scroll-bar value and range. */
WinSendMsg(hwndScroll, SBM_SETSCROLLBAR,
    (MPARAM)300,
    MPFROM2SHORT(200, 400));

You can read a scroll-bar value by sending it an SBM_QUERYPOS message:

USHORT usSliderPos;

/* Read the scroll-bar value. */
usSliderPos = (USHORT) WinSendMsg(hwndScroll,
    SBM_QUERYPOS, (MPARAM) NULL, (MPARAM) NULL);

Similarly, you can set a scroll-bar value by sending an SBM_SETPOS message:

/* Set the vertical scroll-bar value. */
WinSendMsg(hwndScroll, SBM_SETPOS, (MPARAM)300, (MPARAM) NULL);

You can read a scroll-bar range by sending it an SBM_QUERYRANGE message:

MRESULT mr;
USHORT  usMinimum, usMaximum;

/* Read the vertical scroll-bar range. */
mr = WinSendMsg(hwndScroll, SBM_QUERYRANGE, (MPARAM) NULL, (MPARAM) NULL);

usMinimum = SHORT1FROMMR(mr);            /* minimum in the low word  */
usMaximum = SHORT2FROMMR(mr);            /* maximum in the high word */