Visual Basic Common Control API Routines
SetParent: Add a VB Toolbar to a MDI Form's StatusBar
Posted:   Sunday March 28, 2004
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 VB StatusBar

Due to the restrictions MDI parent forms place on the developer a modification in the SetParent: Add a VB Toolbar to a VB StatusBar re-parenting technique is required to re-parent toolbar into a statusbar on the MDI form. While no amount of tweaking will circumvent the MDI requirement that controls placed on the MDI form must support the alignment property, there is a workaround.

The solution lies in placing the status bar and toolbar directly into a picture box which has it's alignment set to bottom.  Now the toolbar and statbar are free to be repositioned as required within the picture box container.

The image below shows the MDI form (grey) and the picture box (yellow), and the control contained in the picture box - the same controls copied right off the form in the non-MDI demo listed above. The non-MDI load code is also copied over, as is the code for the text and combo events (to show the events work when re-parented). The only modification other than the layout method is a reordering of the code within the original AttachSBControl routine to accommodate the quirks of the MDI interface and restrictions. Because the picture box will resize with the form, but not the statbar, you'll want to add additional code handle this in the form's resize event.

 BAS Module Code

 MDI Parent Form Code
On a MDI Parent form, add a picture box (Picture1) and set its align property to bottom. It's design-time height doesn't matter; to debug I find seeing all the controls helpful..

The picture box will contain 5 controls. If you created the non-MDI demo above you can simply copy the controls from that page and paste them all into the picture box.  If you're creating this from scratch you will need a toolbar (ToolBar1), statusbar (StatusBar1), combo box (Combo1), text box(Text1) and command button (Command1) to the form. In addition you'll need to add imagelist controls populated with at least four 16x16 images.

The Load event of the MDI 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 MDIForm_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
      Combo1.ZOrder 0
      Text1.ZOrder 0      
   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
   AttachSBControlMDI 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 AttachSBControlMDI(tb As Toolbar, _
                                    sb As StatusBar, _
                                    nPanel As Long, _
                                    padding As Long)
   Dim x As Long
   Dim y As Long
   If defToolbarHwnd = 0 Then
      sb.Height = tb.Height + padding
      sb.Top = 0
      sb.Left = 0
       With Picture1
         .BorderStyle = 0
         .Appearance = 0
         .Align = vbAlignBottom
         .Height = sb.Height
      End With
      With sb
         .Width = Picture1.ScaleWidth
         tb.Width = 0
         For x = 1 To tb.Buttons.Count
            y = y + tb.Buttons(x).Width
         tb.Width = y + padding
         .Panels(nPanel).AutoSize = sbrNoAutoSize
         .Panels(nPanel).Width = tb.Width + padding

         tb.Visible = True

        'change, move, set width and re-show
        'the toolbar in the new parent
         tb.Align = vbAlignNone
         tb.Appearance = ccFlat
         tb.BorderStyle = ccNone
         tb.Move (.Panels(nPanel).Left + padding), (padding), _
                 (.Panels(nPanel).Width - padding), _
                 (.Height - padding)
        'change the parent
         defToolbarHwnd = SetParent(tb.hWnd, sb.hWnd)
        'bring all the controls to the top
         tb.ZOrder 0
         Combo1.ZOrder 0
         Text1.ZOrder 0
       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 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