Adding Scroll Bars to Forms, PictureBoxes and User Controls

Download the cScrollBar class only (6kb)
Download the Scroll Bar class demonstration project (94kb)
  |
Before you Begin
|
  |
  |
 |
This project requires the SSubTmr.DLL component. Make sure you have loaded and registered this before trying the project.
|
  |
In the Win32 API, all windows can have scroll bars. However, this feature is not exposed
in any way in Visual Basic. Its not too hard to enable, though provided you can intercept
WM_HSCROLL and WM_VSCROLL messages sent to the window. This project provides
a small, self-contained class which extends Forms, UserControls and PictureBoxes to allow
full scroll-bar functionality. This class is based on the
Flat Scroll-Bar control and provides the same functionality but in a smaller, easier-to-use
package which you can compile directly into your executable.
Don't confuse the Win32 windows scroll bars with the scroll bar controls provided with Visual
Basic. The VB scroll bars (at least before VB6) have always been a bit pants: they don't draw
in the neat,professional style of Win32 scroll bars (the worst offense is the continual
flashing when in focus and the fact it is impossible to prevent this occuring!) and they
don't support the full scroll extents (allowing only 16-bit integer values rather than the
full 32-bit offered by Win32).
COMCTL32.DLL v4.72 or above offers enhanced scroll bar controls which support Flat and
Encarta drawing styles as well as the standard styles. This class takes advantage of these
facilities whilst still allowing standard scroll styles regardless of which COMCTL32.DLL
version is installed.
How It Works
Showing a window scroll bar is simple - just call the API call ShowScrollBar with the
Window handle of the control and the appropriate scroll bar constant (SB_HORZ or SB_VERT)
and the scroll bar appears. Windows automatically adjusts the client area of the window
for you, and this is reflected in the values returned by VB's ScaleWidth and ScaleHeight
properties.
Getting and setting scroll bar value, max, min and large-change properties is achieved via
the GetScrollInfo and SetScrollInfo properties, which work on the SCROLLINFO
structure.
' Scroll bar:
Private Type SCROLLINFO
    cbSize As Long     ' Size of structure
    fMask As Long     ' Which value(s) you are changing
    nMin As Long     ' Minimum value of the scroll bar
    nMax As Long     ' Maximum value of the scroll bar
    nPage As Long     ' Large-change amount
    nPos As Long     ' Current value
    nTrackPos As Long     ' Current scroll position
End Type
' SCROLLINFO fMask constants:
Private Const SIF_RANGE = &H1
Private Const SIF_PAGE = &H2
Private Const SIF_POS = &H4
Private Const SIF_DISABLENOSCROLL = &H8
Private Const SIF_TRACKPOS = &H10
Private Const SIF_ALL = (SIF_RANGE Or SIF_PAGE Or SIF_POS Or SIF_TRACKPOS)
Note that the actual Max value of the scroll bar is actually equal to the nMax value plus the
nPage value, so when modifying the LargeChange or Max value you have to take this into account.
This allows you to set up the scroll bars. You then need to respond to the scroll bar position
changing. This is done by intercepting the WM_HSCROLL and WM_VSCROLL messages
sent to the window you have added scroll bars to:
' Scroll bar messages:
Private Const WM_VSCROLL = &H115
Private Const WM_HSCROLL = &H114
' Scroll bar type constants:
Private Const SB_HORZ = 0
Private Const SB_VERT = 1
Private Const SB_CTL = 2
Private Const SB_BOTH = 3
' Scroll bar notification types (returned in the first
' 16 bits of the wParam parameter of the message i.e. (wParam And &HFFFF&):
' - Set scroll value to max
Private Const SB_BOTTOM = 7 ' - Set scroll value to max
Private Const SB_ENDSCROLL = 8 ' - Time to raise Change event
Private Const SB_LEFT = 6 ' - Set scroll value to value - SmallChange
Private Const SB_LINEDOWN = 1 ' - Set scroll value to value + SmallChange
Private Const SB_LINELEFT = 0 ' - Set scroll value to value + SmallChange
Private Const SB_LINERIGHT = 1 ' - Set scroll value to value - SmallChange
Private Const SB_LINEUP = 0 ' - Set scroll value to value + LargeChange
Private Const SB_PAGEDOWN = 3 ' - Set scroll value to value - LargeChange
Private Const SB_PAGELEFT = 2 ' - Set scroll value to value + LargeChange
Private Const SB_PAGERIGHT = 3 ' - Set scroll value to value - LargeChange
Private Const SB_PAGEUP = 2 ' - Set scroll value to max
Private Const SB_RIGHT = 7 ' - Not required?
Private Const SB_THUMBPOSITION = 4 ' - Set scroll value to track position
Private Const SB_THUMBTRACK = 5 ' - Set scroll value to min
Private Const SB_TOP = 6
Once this is done, it is a simple matter to set the appropriate value using the
GetScrollInfo and SetScrollInfo API methods. These ensure you have
access to the full 32bit range for the scroll bar rather than the old 16 bit
(-32,768 to 32,767) values. (If you are using Flat Scroll bars, then use the FlatSB_ versions of these instead).
The cScrollBars.cls code in the downloads shows how it is done.
Quick Start: Using the Class
This demonstrates how to add a vertical scroll bar to a VB form.
- Start a new project and add a reference to the SSUBTMR.DLL (it appears in the References box as "Subclassing and Timer Assistant
(with multi-control support and timer bug fix)"). Then add the cScrollBars.cls to the project.
- Now declare an instance of the cScrollBars in the declarations section of your form:
Private WithEvents m_cScroll As cScrollBars
During the Form_Load event, initialise the scroll bars:
Private Sub Form_Load()
    ' Set up scroll bars:
    Set m_cScroll = New cScrollBars
    m_cScroll.Create Me.hwnd
End Sub
Now your scroll bars are set up. Initially, they will not work however until you set Minimum, Maximum, LargeChange and
SmallChange properties. Normally your scroll bar ranges change when the form is resized (not in this simple example,
though) so the easiest place to do this is in the Form_Resize event. If you are scrolling an
object on the form, remember that the smallest amount the object can move will be 1 pixel. Therefore don't set a
scroll bar range in Twips because it will mean it will take Screen.TwipsPerPixel (normally 15) scroll bar steps
before it moves:
Private Sub Form_Resize()
    With m_cScroll
        ' Set up vertical scroll bar for 1024 steps:
        .LargeChange(efsVertical) = 64
        .SmallChange(efsVertical) = 8
        .Max(efsVertical) = 1024
        .Visible(efsVertical) = True
        ' Hide horizontal scroll bar:
        .Visible(efsHorizontal) = False
    End With
End Sub
Finally, you can respond to the scroll bar events. For this example we will just update a Label, so add a Label
control to the form and then this code:
Private Sub m_cScroll_Change(eBar As EFSScrollBarConstants)
    Label1.Caption = m_cScroll.Value(efsVertical)
End Sub
Private Sub m_cScroll_Scroll(eBar as EFSScrollBarConstants)
    m_cScroll_Change eBar
End Sub
Run the project. The form will have a vertical scroll bar and the label will update when you scroll it.
The demonstration project shows how to use the scroll bars in three ways:
- To scroll the controls on a form
- To scroll an Image within a PictureBox
- To scroll a very simple owner-draw grid within a PictureBox.
For a more complex demonstration of the cScrollBars class, check out the vbAccelerator
S-Grid control.
Back to top
Back to Source Code
|