Visual Basic Common Control API Routines
Adding a VB Toolbar to a VB StatusBar
Posted:   Sunday January 20, 2002
Updated:   Monday December 26, 2011
Applies to:   VB4-32, VB5, VB6
Developed with:   VB6, Windows XP
OS restrictions:   None
Author:   VBnet - Randy Birch
Related:   SetParent: Add a VB Toolbar to a MDI Form's StatusBar

This code was prompted by a newsgroup request for code to place a VB command button inside a VB status bar such that the button reacted normally to events yet was contained inside the status bar panel area. Attempts to use SetParent against the command button worked to re-parent the control, however once the parent was changed the button's events failed to fire.  In experimenting, I found that a regular VB toolbar did fire its events after re-parenting.  I became curious to see if VB controls placed into a toolbar placeholder also raised events after the SetParent call, and was pleasantly surprised to find they did. This demo is the result of the experiment.

The toolbar can not have its alignment property set on the form prior to calling SetParent. In addition, since the offset position of a toolbar is always relative to the upper left of the form (regardless of parent), I normally I would have added extra code to calculate and move the toolbar into position in relation to the status bar location using this offset.  But I found that I could cheat this need by, at the moment of parenting the toolbar, resetting the alignment property of the status bar to the form top providing a natural offset to the form's corner. Therefore, this code on re-parenting hides the toolbar and status bar, adjusts the control's alignment, calculates the horizontal offset to the panel specified as the 'home' for the toolbar, changes the parent, and re-shows the controls aligned at the bottom of the form.

The status bar panel containing the toolbar uses the default AutoSize (no sizing), thereby assuring that the toolbar remains in the current position in the status bar (and as long as all other panels preceding the toolbar panel has this same sizing style).  For those wishing to position the toolbar inside the right-most panel to simulate an appearance like Netscape's command toolbar, you will need to add extra code to detect when the form is resized, the new position of the toolbar panel, and then move the toolbar to this new location. Those happy with the buttons on the left (or in any panel so long as all preceding it are sbrNoAutoSize), this code works without change.

The Load event of the form handles all the details in creating the toolbar and status bar for this demo. All that is required in addition to a blank toolbar, blank status bar, combo box, text box and command button is an imagelist control containing the button's icons.

Note: the combo and text are for demo purposes regarding events. When placed into the status bar, I found their redraw less than optimal should the form be resized horizontally. Vertical resizing seemed to redraw the controls without problem.

Note: For MDI forms a modified method is required - see .

 BAS Module Code

 Form Code
Add a toolbar (ToolBar1), statusbar (StatusBar1), combo box (Combo1), text box(Text1) and command button (Command1) to the form. Add an imagelist controls and populate with at least 4 16x16 images. The Load event of the form handles all the details in creating the toolbar buttons and status bar panels for this demo. Paste the following code into the form:

Option Explicit
' Copyright 1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
Private defToolbarHwnd As Long

Private Declare Function SetParent Lib "user32" _
  (ByVal hWndChild As Long, _
   ByVal hWndNewParent As Long) As Long

Private Sub Form_Load()

   Dim pnl As Panel
   Dim btn As Button
   Dim x As Long
  'create statusbar
   With StatusBar1
      For x = 1 To 3
         Set pnl = .Panels.Add(, , "", sbrText)
         pnl.Alignment = sbrLeft
         pnl.Width = 500
         pnl.Bevel = sbrInset
         If x = 3 Then pnl.AutoSize = sbrSpring
   End With
  'create toolbar
   With Toolbar1
      .Align = vbAlignNone
      .BorderStyle = ccNone
      .Appearance = ccFlat
      .TextAlignment = tbrTextAlignBottom
      .Wrappable = False
      .AllowCustomize = False
      .ImageList = ImageList1
      .HotImageList = ImageList1
      .Style = tbrFlat
      Set btn = .Buttons.Add(, , , tbrDefault, 1)
      Set btn = .Buttons.Add(, , , tbrDefault, 2)
      Set btn = .Buttons.Add(, , "", tbrSeparator)
      Set btn = .Buttons.Add(, "phtext", "", tbrPlaceholder)
      btn.Width = 1500
      Set btn = .Buttons.Add(, , "", tbrSeparator)
      Set btn = .Buttons.Add(, , , tbrDefault, 3)
      Set btn = .Buttons.Add(, , , tbrDefault, 4)
      Set btn = .Buttons.Add(, , "", tbrSeparator)
      Set btn = .Buttons.Add(, "phcombo", "", tbrPlaceholder)
      btn.Width = 840
      Set Combo1.Container = Toolbar1
      Set Text1.Container = Toolbar1
   End With
  'create combo
   With Combo1
      .Width = Toolbar1.Buttons("phcombo").Width
      .Top = (Toolbar1.Height - .Height) \ 2
      .Left = Toolbar1.Buttons("phcombo").Left
      .AddItem "Red"
      .AddItem "Blue"
      .AddItem "Green"
      .AddItem "Grey"
      .ListIndex = 3
   End With
  'create text
   With Text1
      .Width = Toolbar1.Buttons("phtext").Width
      .Top = (Toolbar1.Height - .Height) \ 2
      .Left = Toolbar1.Buttons("phtext").Left
      .Text = "type query here"
   End With

   Command1.Caption = "Set Toolbar"
End Sub

Private Sub Command1_Click()

   Dim padding As Long
   padding = 60
   AttachSBControl Toolbar1, StatusBar1, 1, padding
End Sub

Private Sub Form_Resize()

End Sub

Private Sub Form_Unload(Cancel As Integer)
   If defToolbarHwnd <> 0 Then
      SetParent Toolbar1.hWnd, defToolbarHwnd
   End If
End Sub

Private Function AttachSBControl(tb As Toolbar, _
                                 sb As StatusBar, _
                                 nPanel As Long, _
                                 padding As Long)
   Dim x As Long
   Dim y As Long
   If defToolbarHwnd = 0 Then
     'change the parent
      defToolbarHwnd = SetParent(tb.hWnd, sb.hWnd)
      With sb
        'adjust statusbar. Doing it this way
        'relieves the necessity of calculating
        'the statusbar position relative to the
        'top of the form. It happens so fast
        'the change is not seen, other than
        'the height resizing.
         .Align = vbAlignTop
         .Visible = False
         .Height = tb.Height + padding
        'change, move, set width and re-show
        'the toolbar in the new parent
         tb.Visible = False
         tb.Align = vbAlignNone
         tb.Appearance = ccFlat
         tb.BorderStyle = ccNone
         tb.Move (.Panels(nPanel).Left + padding), _
                 (.Top + padding), _
                 (.Panels(nPanel).Width - padding), _
                 (.Height - padding)
         tb.Width = 0
         For x = 1 To tb.Buttons.Count
            y = y + tb.Buttons(x).Width
         tb.Width = y + padding
         tb.Visible = True
         tb.ZOrder 0
        'restore the statusbar to the
        'bottom of the form and show
         .Panels(nPanel).AutoSize = sbrNoAutoSize
         .Panels(nPanel).Width = tb.Width + padding
         .Align = vbAlignBottom
         .Visible = True
       End With
    End If
End Function

Private Sub Text1_GotFocus()

  'show event is raised
   With Text1
      .SelStart = 0
      .SelLength = Len(.Text)
   End With
End Sub

Private Sub Toolbar1_ButtonClick(ByVal Button As MSComctlLib.Button)

  'show event is raised
   Select Case Button.Index
      Case 1: Me.BackColor = &H80&
      Case 2: Me.BackColor = &H800000
      Case 6: Me.BackColor = &H8000&
      Case 7: Me.BackColor = &H8000000F
      Case Else
   End Select
End Sub

Private Sub Toolbar1_ButtonMenuClick(ByVal ButtonMenu As MSComctlLib.ButtonMenu)

  'show event is raised
   Select Case ButtonMenu.Index
      Case 1: Me.BackColor = &H80&
      Case 2: Me.BackColor = &H800000
      Case 5: Me.BackColor = &H8000000F
      Case 6: Me.BackColor = &H0
   End Select
End Sub

Private Sub Combo1_Click()

  'show event is raised
   Select Case Combo1.ListIndex
      Case 0: Me.BackColor = &H80&
      Case 1: Me.BackColor = &H800000
      Case 2: Me.BackColor = &H8000&
      Case 3: Me.BackColor = &H8000000F
   End Select
End Sub


PayPal Link
Make payments with PayPal - it's fast, free and secure!


Copyright 1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy


Hit Counter