Splitter Bars

Category: Application Features

Date: 03-28-2012

Return to Index


 
'Features:
'1. Two different layouts
'2. Both a horizontal and vertical splitter bars (horizontal bar can be removed)
'3. Splitter bar positions can be fixed position or positioned on a percentage basis
 
'Primary Code;
'Due to the length of this example, on a description will be covered in this section.
'See the compilable example below for the source code.
 
'Splitter bar action is accomplished by detecting the presence of a mouse click and
'drag movement. This can be done by monitoring mouse action over a control, over simply
'over an area of the dialog. This approach uses label controls as the splitter bars - one
'for vertical splitting and one for horizontal splitting.
 
'The code sections/functions used in the compilable example below are:
'1. %WM_SetCursor            - detects mouse clicks and movement
'2. Sub MoveBarUpDown        - moves horizontal bar in response to mouse action
'3. Sub MoveBarLeftRight     - moves vertical bar in response to mouse action
'4. Sub ResizeWindow         - adjusts controls in response to user resizing of dialog
'5. Sub ResizeSplitterBars   - adjust splitter bars in response to user resizing of dialog
'6. Sub SetControlVisibility - used to show/hide controls according to layout option selection
 
 
'Compilable Example:
#Compiler PBWin 9, PBWin 10
#Compile EXE
#Dim All
#Debug Error On     'catch array/pointer errors - OFF in production
#Debug Display On   'display untrapped errors   - OFF in production
#Include "Win32api.inc"
#Resource "gbsnippets.pbr"
 
%IDC_Left = 500 : %IDC_Right = 501 : %IDC_Bottom = 502
%IDC_LabelH = 532 : %IDC_LabelV = 533 : %IDC_StatusBar = 536 : %IDM_Alternate = 534
%IDC_Toolbar = 537 : %IDM_ShowBottom = 600 : %IDM_Fixed = 601 : %IDT_New = 602
%ID_ImageList = 700 : %IDT_X = 701 : %IDT_Y = 702 : %IDT_Z = 703
 
' Global Variables: handles =============================================================
Global hDlg As DWord, hTree As DWord, hList As DWord, hMenu As DWord
Global SplitVInWork As Long, SplitHInWork As Long, ShowBottom&, hMenuOptions As DWord
Global XSplit As Single, YSplit As Single, AlternateLayout&, hLst as DWord
Global HBarLeft As Long, VBarTop As Long, FixedSplitterBar&
 
' Main Function =======================================================================
 
Function PBMain()
   Dialog New Pixels, 0, "Splitter Text",300,300,410,340, %WS_OverlappedWindow Or %WS_ClipChildren To hDlg
   Control Add StatusBar, hDlg, %IDC_StatusBar, "",0,0,0,0     'xy, xxyy ignored, %ccs_bottom by default
 
   Control Add Toolbar, hDlg, %IDC_Toolbar, "Toolbar",0,0,0,0                    'xy, xxyy, txt$ ignored, %ccs_top by default
   'create imagelist for Toolbar
   ImageList New Icon 16,16,32,3 To hLst
   ImageList Add Icon hLst, "x"              '1
   ImageList Add Icon hLst, "y"              '2
   ImageList Add Icon hLst, "z"              '3
   'attach imagelist
   Toolbar Set ImageList hDlg, %IDC_Toolbar, hLst, 0
   'create buttons
   Toolbar Add Button  hDlg, %IDC_Toolbar, 1, %IDT_X, %TbStyle_Check, "X"
   Toolbar Add Button  hDlg, %IDC_Toolbar, 2, %IDT_Y, %TbStyle_Check, "Y"
   Toolbar Add Button  hDlg, %IDC_Toolbar, 3, %IDT_Y, %TbStyle_Check, "Z"
 
   'create menu
   Menu New Bar To hMenu
   Menu New Popup To hMenuOptions
   Menu Add Popup, hMenu, "&Options", hMenuOptions, %MF_Enabled
   Menu Add String, hMenuOptions, "&Alternate Layout", %IDM_Alternate, %MF_Enabled
   Menu Add String, hMenuOptions, "&Hide Bottom", %IDM_ShowBottom, %MF_Enabled
   Menu Add String, hMenuOptions, "&Fixed Position", %IDM_Fixed, %MF_Enabled
   Menu Attach hMenu, hDlg
 
   'add the controls + splitter bars (labels)
   Control Add TextBox, hDlg, %IDC_Left, "TopLeft",  20, 80, 160, 80
   Control Add TextBox, hDlg, %IDC_Bottom, "Bottom",  20, 200, 370, 90
   Control Add TextBox, hDlg, %IDC_Right, "TopRight", 220, 55, 170, 100
   Control Add Label, hDlg, %IDC_LabelH, "",  200, 45, 6, 125, %SS_Notify , %WS_Ex_ClientEdge  ' up/down - does horizontal split
   Control Add Label, hDlg, %IDC_LabelV, "",  0,170, 410, 6, %SS_Notify , %WS_Ex_ClientEdge   ' left/right - does vertical split
 
   XSplit = 0.5 : YSplit = 0.5 : ShowBottom& = 1 : HBarLeft = 100 : VBarTop = 100
   Menu Set State hMenuOptions, ByCmd %IDM_ShowBottom, ShowBottom& * 8
 
   Dialog Show Modal hDlg Call DlgProc()
End Function
 
   'monitor mouse movement=================================
 
CallBack Function DlgProc() As Long
   Local iReturn As Long, x as Long, y as Long, w as Long, h as Long
   Select Case CB.Msg
      Case %WM_Command
         Select Case CB.Ctl
            Case %IDM_Alternate
               AlternateLayout& = AlternateLayout&  XOR 1     'flip between 0 and 1
               Menu Set State hMenuOptions, ByCmd %IDM_Alternate, AlternateLayout& * 8
               ResizeWindow
            Case %IDM_ShowBottom
               ShowBottom& = ShowBottom&  XOR 1     'flip between 0 and 1
               Menu Set State hMenuOptions, ByCmd %IDM_ShowBottom, ShowBottom& * 8
               ResizeWindow
            Case %IDM_Fixed
               FixedSplitterBar& = FixedSplitterBar&  XOR 1     'flip between 0 and 1
               Menu Set State hMenuOptions, ByCmd %IDM_Fixed, FixedSplitterBar& * 8
               Dialog Get Client hDlg To w,h
               'adjusts VBarTop/HBarLeft or xSplit/ySplit when option is changed
               'both are not kept current at all times - only the pair in use
               If FixedSplitterBar& Then
                  VBarTop = h - ySplit * h
                  HBarLeft = xSplit * w
               Else
                  ySplit = (h-VBarTop) / h
                  xSplit = HBarLeft / w
               End If
               ResizeWindow
            Case %IDT_X, %IDT_Y, %IDT_Z
               MsgBox "No action. Toolbar included just to show how splitter bars work with toolbar in place.", %MB_OK + %MB_IconInformation, "Toolbar Button Pressed"
         End Select
      Case %WM_Size
         ResizeWindow
      Case %WM_SetCursor
         iReturn = GetDlgCtrlID (CB.wParam)
         'identify over which label control the mouse action took place
         If iReturn = %IDC_LabelH Then MousePTR 9 : Function = 1    '9 = horizontal cursor
         If iReturn = %IDC_LabelV Then MousePTR 7 : Function = 1    '7 = vertical cursor
 
         'monitors the 3 basic splitter bar mouse actions, lbuttondown, mousemose, lbuttonup
         Select Case Hi(Word, CB.lParam)
            Case %WM_LButtonDown
               'sets flags to say splitter action has started (no actual movement yet)
               If iReturn = %IDC_LabelV Then SplitVInWork = 1
               If iReturn = %IDC_LabelH Then SplitHInWork = 1
            Case %WM_MouseMove
               'Repositions splitter bars to match mouse position (if position has changed)
               If SplitVInWork Then If MoveBarUpDown Then ResizeWindow
               If SplitHInWork Then If MoveBarLeftRight Then ResizeWindow
            Case %WM_LButtonUp
               'sets flags to say splitter action has ended
               SplitHInWork = 0 : SplitVInWork = 0
         End Select
   End Select
End Function
 
Function MoveBarUpDown As Long
   Local pt As Point, h As Long, w As Long
   Static oldY As Long
   Dialog Get Client hDlg To w,h
   GetCursorPos pt               'pt has xy screen coordinates
   ScreenToClient hDlg, pt       'pt now has client coordinates
   '    If h-pt.y < 50 Then Exit Function   'limit right motion   'optional
   '    If pt.y < 50 Then Exit Function                            'optional
   YSplit = (pt.y-3) / h         'actually, should only do one or the other
   VBarTop = h - (Pt.y-3)        'actually, should only do one or the other
   If pt.y <> oldY Then Function = %True : oldY = pt.y
End Function
 
Function MoveBarLeftRight As Long
   Local pt As Point, h As Long, w As Long
   Static oldX As Long
   Dialog Get Client hDlg To w,h
   GetCursorPos pt               'pt has xy screen coordinates
   ScreenToClient hDlg, pt       'pt now has client coordinates
   '    If w-pt.x < 50 Then Exit Function   'limit right motion       'optional
   '    If pt.x < 50 Then Exit Function                                 'optional
   XSplit = (pt.x-3) / w        'actually, should only do one or the other
   HBarLeft = pt.x-3            'actually, should only do one or the other
   If pt.x <> oldX Then Function = %True : oldX = pt.x
End Function
 
Sub ResizeWindow
   Local vx As Long, vy As Long, hx As Long, hy As Long, h As Long, w As Long
 
   SetControlVisibility
   ResizeSplitterBars
 
   Dialog Get Size hDlg To w,h
   Control Get Loc hDlg, %IDC_LabelH To hx, hy
   Control Get Loc hDlg, %IDC_LabelV To vx, vy
 
   'Resize  controls
   If ShowBottom& = 0 Then
      'simple side by side of tree and richedit
      Control Set Loc  hDlg, %IDC_Left, 5, 47
      Control Set Size hDlg, %IDC_Left, hx - 10, h - 122
      Control Set Loc  hDlg, %IDC_Right, hx + 9, 47
      Control Set Size hDlg, %IDC_Right, w - hx - 24, h - 122
 
      StatusBar Set Parts hDlg, %IDC_StatusBar, w/3, w/3, w/3
 
   ElseIf AlternateLayout& = 0 Then
      'left beside right - both over bottom
      Control Set Loc  hDlg, %IDC_Left, 5, 47
      Control Set Size hDlg, %IDC_Left, hx - 10, vy - 50
 
      Control Set Loc  hDlg, %IDC_Right, hx + 9, 47
      Control Set Size hDlg, %IDC_Right, w - hx - 24, vy - 50
 
      Control Set Loc  hDlg, %IDC_Bottom, 5, vy + 8
      Control Set Size hDlg, %IDC_Bottom, w - 20, h - vy - 85
 
      StatusBar Set Parts hDlg, %IDC_StatusBar, w/3, w/3, w/3
 
   ElseIf AlternateLayout& Then
      'left over bottom, right top-to-bottom of page
      Control Set Loc  hDlg, %IDC_Left, 5, 47
      Control Set Size hDlg, %IDC_Left, hx - 10, vy - 50
 
      Control Set Loc  hDlg, %IDC_Right, hx + 9, 47
      Control Set Size hDlg, %IDC_Right, w - hx - 24, h - 122
 
      Control Set Loc  hDlg, %IDC_Bottom, 5, vy + 8
      Control Set Size hDlg, %IDC_Bottom, hx - 10, h - vy - 85
 
      StatusBar Set Parts hDlg, %IDC_StatusBar, w/3, w/3, w/3
 
   End If
 
   Dialog Redraw hDlg
 
End Sub
 
Sub ResizeSplitterBars
   Local h As Long, w As Long, HLeft As Long, VTop As Long
   Dialog Get Client hDlg To w,h
 
   'position does not depend on layout
   If FixedSplitterBar& Then
      VTop = h - VBarTop
      HLeft = HBarLeft
   Else
      VTop = ySplit*h
      HLeft = xSplit*w
   End If
 
   Control Set Loc hDlg,  %IDC_LabelV, 5, VTop
   Control Set Loc hDlg,  %IDC_LabelH, HLeft, 45
 
   If ShowBottom& = 0 Then
      Control Set Size hDlg, %IDC_LabelH, 6, h-66           'tree + richedit only
   ElseIf AlternateLayout& = 0 Then
      Control Set Size hDlg, %IDC_LabelV, w-12, 6
      Control Set Size hDlg, %IDc_LabelH, 6, VTop-48
   ElseIf AlternateLayout& Then
      'tree over listview. richedit top-to-bottom of page
      Control Set Size hDlg, %IDC_LabelV, HLeft-10, 6
      Control Set Size hDlg, %IDC_LabelH, 6, h - 66
   End If
End Sub
 
Sub SetControlVisibility
   'Find controls are always visible
   'Left, Right Controls are always visible
   If ShowBottom& = 0 Then
      'simple side by side of left and right (no bottom)
      Control Show State hDlg, %IDC_LabelV, %SW_Hide
      Control Show State hDlg, %IDC_Bottom, %SW_Hide
      Control Show State hDlg, %IDC_Statusbar, %SW_Show
   Else
      'either layout, with bottom showing
      'left beside right, both ver bottom OR
      'left over bottom, right top-to-bottom of page
      Control Show State hDlg, %IDC_LabelV, %SW_Show
      Control Show State hDlg, %IDC_Bottom, %SW_Show
      Control Show State hDlg, %IDC_Statusbar, %SW_Show
   End If
End Sub
 
'gbs_00060
'Date: 03-10-2012


created by gbSnippets
http://www.garybeene.com/sw/gbsnippets.htm