The new vbAccelerator Site - more VB and .NET Code and Controls
Source Code


 NOTE: this code has been superceded by the version at the new site.



3 Code Libraries Source Code &nbsp
&nbsp

Splitting the Easy Way

Download the cSplitter Class (2kb)

The cSplitter class demonstrates a very simple way to add splitter functionality to your application. There are undoubtedly more flexible and difficult ways of doing this (I'm currently trying to develop one using transparent windows) but this is the method I've used up to now.

In this method, a PictureBox is used as the splitter for the form. The splitter class automatically sets the MousePointer for the PictureBox to the NS or EW depending on the orientation you want, so when the mouse moves over the PictureBox, the user sees that they can click and drag the splitter in the right direction.

When the user clicks on it, the Splitter class then calls the SetCapture method to redirect subsequent MouseMoves onto the owning form of the splitter. This makes it easier to work out where the splitter should be positioned as the mouse moves over the form. Finally, when the mouse is released, the class evaluates if the splitter is being dropped with allowable bounds, releases the mouse capture to the form and raises an event saying the split is complete.

Here is the code:

' cSplitter
Private Declare Function SetCapture Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseCapture Lib "user32" () As Long

' If we used WithEvents on these items, then we not need to
' write any code at all in the form being split. However, this
' means you have a a WithEvents reference to the form here, whilst
' the form also has a WithEvents reference to the splitter.
' This seems to cause immediate crash (VB dev environment disappears!)
' when trying to terminate the splitter class under VB5 (SP2 and above)
Private m_picSplitter As PictureBox
Private m_frmParent As Form

Private m_bSplitting As Boolean
Private m_lSplitOffset As Long
Private m_lBorder As Long
Private m_eOrientation As ESPLTOrientationConstants

Public Enum ESPLTOrientationConstants
&nbsp &nbsp cSPLTOrientationHorizontal = 1
&nbsp &nbsp cSPLTOrientationVertical = 2
End Enum

Public Event DoSplit(bSplit As Boolean)
Public Event SplitComplete()

Property Let Orientation(eOrientation As ESPLTOrientationConstants)
&nbsp &nbsp m_eOrientation = eOrientation
&nbsp &nbsp If Not (m_picSplitter Is Nothing) Then
&nbsp &nbsp &nbsp &nbsp If (eOrientation = cSPLTOrientationHorizontal) Then
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp m_picSplitter.MousePointer = vbSizeNS
&nbsp &nbsp &nbsp &nbsp Else
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp m_picSplitter.MousePointer = vbSizeWE
&nbsp &nbsp &nbsp &nbsp End If
&nbsp &nbsp End If
End Property
Property Get Orientation() As ESPLTOrientationConstants
&nbsp &nbsp Orientation = m_eOrientation
End Property
Property Let BorderSize(lSize As Long)
&nbsp &nbsp m_lBorder = lSize
End Property
Property Get BorderSize() As Long
&nbsp &nbsp BorderSize = m_lBorder
End Property
Public Sub Initialise( _
&nbsp &nbsp &nbsp &nbsp ByRef picSplitter As PictureBox, _
&nbsp &nbsp &nbsp &nbsp ByRef frmParent As Form _
&nbsp &nbsp )
&nbsp &nbsp Set m_picSplitter = picSplitter
&nbsp &nbsp Set m_frmParent = frmParent
&nbsp &nbsp With m_picSplitter
&nbsp &nbsp &nbsp &nbsp .BorderStyle = 0
&nbsp &nbsp &nbsp &nbsp .ZOrder 1
&nbsp &nbsp &nbsp &nbsp .MousePointer = vbSizeWE
&nbsp &nbsp &nbsp &nbsp .Visible = True
&nbsp &nbsp End With
End Sub
Public Sub MouseDown( _
&nbsp &nbsp &nbsp &nbsp ByVal Pos As Single _
&nbsp &nbsp )
Dim bSplit As Boolean
&nbsp &nbsp bSplit = True
&nbsp &nbsp RaiseEvent DoSplit(bSplit)
&nbsp &nbsp If Not (bSplit) Then Exit Sub
&nbsp &nbsp
&nbsp &nbsp m_bSplitting = True
&nbsp &nbsp m_lSplitOffset = Pos
&nbsp &nbsp With m_picSplitter
&nbsp &nbsp &nbsp &nbsp .BackColor = &H80000010
&nbsp &nbsp &nbsp &nbsp .ZOrder 0
&nbsp &nbsp &nbsp &nbsp .BorderStyle = 1
&nbsp &nbsp &nbsp &nbsp .Width = 4 * Screen.TwipsPerPixelX
&nbsp &nbsp End With
&nbsp &nbsp SetCapture m_frmParent.hwnd
End Sub
Public Sub MouseMove( _
&nbsp &nbsp &nbsp &nbsp ByVal Pos As Single _
&nbsp &nbsp )
&nbsp &nbsp If (m_bSplitting) Then
&nbsp &nbsp &nbsp &nbsp If (m_eOrientation = cSPLTOrientationHorizontal) Then
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp ' Horizontal orientation:
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp If (Pos m_lBorder) Then
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp Screen.MousePointer = vbSizeNS
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp m_picSplitter.Move m_picSplitter.Left, Pos
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp Else
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp Screen.MousePointer = vbNoDrop
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp End If
&nbsp &nbsp &nbsp &nbsp Else
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp ' Vertical orientation:
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp If (Pos m_lBorder) Then
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp Screen.MousePointer = vbSizeWE
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp m_picSplitter.Move Pos
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp Else
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp Screen.MousePointer = vbNoDrop
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp End If
&nbsp &nbsp &nbsp &nbsp End If
&nbsp &nbsp End If
End Sub
Public Function MouseUp( _
&nbsp &nbsp &nbsp &nbsp ByRef Pos As Single _
&nbsp &nbsp ) As Boolean
Dim lRealPos As Long

&nbsp &nbsp If (m_bSplitting) Then
&nbsp &nbsp &nbsp &nbsp ' End the moving:
&nbsp &nbsp &nbsp &nbsp ReleaseCapture
&nbsp &nbsp &nbsp &nbsp With m_picSplitter
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp .BackColor = &H8000000F
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp .BorderStyle = 0
&nbsp &nbsp &nbsp &nbsp
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp ' Move to a position within bounds
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp ' if we are out of bounds:
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp If (Pos &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp Pos = m_lBorder
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp End If
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp If (m_eOrientation = cSPLTOrientationHorizontal) Then
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp If (Pos > (m_frmParent.ScaleHeight - m_lBorder)) Then
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp Pos = m_frmParent.ScaleHeight - m_lBorder
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp End If
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp Else
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp If (Pos > (m_frmParent.ScaleWidth - m_lBorder)) Then
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp Pos = m_frmParent.ScaleWidth - m_lBorder
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp End If
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp End If
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp ' Now drop the splitter:
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp Pos = Pos - m_lSplitOffset
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp If (m_eOrientation = cSPLTOrientationHorizontal) Then
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp .Move .Left, Pos
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp Else
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp .Move Pos
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp End If
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp .ZOrder 1
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp
&nbsp &nbsp &nbsp &nbsp End With
&nbsp &nbsp &nbsp &nbsp
&nbsp &nbsp &nbsp &nbsp m_bSplitting = False
&nbsp &nbsp &nbsp &nbsp Screen.MousePointer = vbNormal
&nbsp &nbsp &nbsp &nbsp
&nbsp &nbsp &nbsp &nbsp MouseUp = True
&nbsp &nbsp &nbsp &nbsp
&nbsp &nbsp &nbsp &nbsp RaiseEvent SplitComplete
&nbsp &nbsp End If
End Function

Private Sub Class_Initialize()
&nbsp &nbsp m_eOrientation = cSPLTOrientationVertical
End Sub


Private Sub Class_Terminate()
&nbsp &nbsp m_bSplitting = False
&nbsp &nbsp Set m_picSplitter = Nothing
&nbsp &nbsp Set m_frmParent = Nothing
End Sub


To use the splitter
Draw a PictureBox on the form, called picSplit (say). In the Form declarations section, declare a splitter variable:

&nbsp &nbsp Private WithEvents m_cSplit As cSplitter

In Form_Load, initalise your splitter:

&nbsp &nbsp Set m_cSplit = New cSplitter
&nbsp &nbsp m_cSplit.Initialise picSplit, Me

Then add the code to direct mouse events to the splitter class. In picSplit_MouseDown, put:

&nbsp &nbsp m_cSplit.MouseDown X ' Use Y if the splitter is horizontal

Under the Form_MouseMove and Form_MouseUp events:

&nbsp &nbsp m_cSplit.MouseMove X
&nbsp &nbsp m_cSplit.MouseUp X

Finally, from the m_cSplit_SplitComplete event, you can call your form resize code.


To try a fully working demo, download the RegEdit demonstration application.

Back to top

Back to Source Code Overview

&nbsp
 

About  Contribute  Send Feedback  Privacy

Copyright © 1998-1999, Steve McMahon ( steve@vbaccelerator.com). All Rights Reserved.
Last updated: 21 June 1998