By Peter Aitken

This article
originally appeared in the
Visual Basic e-newsletter. Click
to subscribe automatically.

Many Windows programs use a window with panes separated by a
splitter. You can drag the splitter to make one pane larger and the other
smaller–without changing the parent window size. While Visual Basic 6 doesn’t
provide a control for this purpose, you can do it yourself.

Picture this

The technique for creating a pane splitter makes use of the
fact that you can use a Picture Box control as a container for other controls.
When designing the form, place two Picture Box controls on the form, one for
each pane. You can call them pbTop and pbBottom, for example, for the upper and lower panes. Then,
place the other controls for each pane on the corresponding Picture Box.

When the program runs, code arranges the two Picture Box
controls (the two panes) to fill the window at predefined sizes. The sizes are
computed so that a thin strip of the underlying form shows through between the
Picture Boxes; this will serve as the splitter.

Set the form’s MousePointer property to “7 – Size NS” so that an
up/down sizing cursor will display when the mouse is over the splitter. Set
each Picture Box control’s MousePointer property to “1 – Arrow.” The program
also needs constants for the splitter height and for the minimum permitted
height of each pane.

Related resources

“Reap the benefits of using VB ActiveX .dll
files in Active Server Pages”

“Discussion question: VB 6 data report designer”

Here’s what happens

When the user starts dragging the splitter, the new splitter
position is determined from the position of the mouse cursor. This occurs in
the MouseMove
event procedure. A procedure named ChangePaneSizes is called; code in this procedure uses the
new splitter position to change the sizes of the two panes accordingly. Neither
pane is permitted to be smaller than the specified minimum.

Below is code to perform these actions. You can try this out
by creating a VB program with a form that contains two Picture Box controls
named pbTop
and pbBottom;
then, paste this code into the form’s code window. This example is for two
panes separated by a horizontal splitter, but you could adapt it for other pane
arrangements as well.

Option Explicit


‘ The percentage of the window height
‘ occupied by the top pane.
Dim TopPanePercentAs Single
‘ True when the splitter is being dragged.
Private Dragging As Boolean

Private Sub ChangePaneSizes()

    ‘ Arrange the panes according to the new splitter position.
    Dim TopHeightAs Single
    Dim BottomHeight As Single

    ‘ Do nothing if window is minimized.
    If WindowState = vbMinimized Then Exit Sub

    TopHeight = (ScaleHeight – SPLITTER_HEIGHT) * TopPanePercent
    If TopHeight < MIN_PANE_HEIGHT Then TopHeight = MIN_PANE_HEIGHT
    pbTop.Move 0, 0, ScaleWidth, TopHeight
    BottomHeight = (ScaleHeight – SPLITTER_HEIGHT) – TopHeight
    If BottomHeight >= MIN_PANE_HEIGHT Then
        pbBottom.Move 0, TopHeight + SPLITTER_HEIGHT, ScaleWidth, BottomHeight
    End If
End Sub

Private Sub Form_Load()
    ‘ Initially each pane gets half the window.
    TopPanePercent = 0.5
End Sub

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, _
  Y As Single)
    ‘ Start dragging the splitter.
    Dragging = True
End Sub

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, _
  Y As Single)
    ‘ As the splitter is dragged.
    ‘ Do nothing if we’re not dragging.
    If Not Dragging Then Exit Sub

    TopPanePercent = Y / ScaleHeight
    If TopPanePercent < 0 Then TopPanePercent = 0
    If TopPanePercent > 1 Then TopPanePercent = 1
End Sub

Private Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, _
  Y As Single)
    ‘ End dragging the splitter.
    Dragging = False
End Sub

Private Sub Form_Resize()
    ‘ Change pane sizes if the window is resized.
End Sub

Peter Aitken has been programming with Visual Basic since Version 1.0. He has
written numerous books and magazine articles on Visual Basic and other computer
and programming topics.