Visual Basic Common Control API Routines
FindWindowEx: Fix the IE5/MsComCtrl 5 Toolbar Problem
Posted:   Friday September 17, 1999
Updated:   Monday December 26, 2011
Applies to:   VB4-32, VB5, VB6
Developed with:   VB5, Windows 95
OS restrictions:   None
Author:   VBnet - Randy Birch


FindWindowEx: Change a VB Toolbar to a Rebar-Style Toolbar
This method is intended for Visual Basic 5 or Visual Basic 6 where the Common Control library used is the MSComCtl 5 version (comctl32.ocx). Because the VB6-specific mscomctl.ocx (Common Controls 6) is a complete implementation of comctl32.dll and not reliant on the version of comctl32.dll installed, this routine may not work when applied to a listview created from the VB6-specific mscomctl.ocx.

Enhanced Comctl32 functionality is only available to users with comctl32.dll version 4.70 or greater installed. This dll is typically installed with IE3.x or greater.

After the introduction of IE5, users began complaining that their code, which had previously created flat toolbars, failed on systems with IE5 installed. In addition, whenever the text (caption) for a button was changed through code, and the new caption text length differed from that being replaced, all button captions for that toolbar would disappear.

Illustration one, shows the basic demo project in its initial state. The project consists of four VB5 toolbar controls applied to a form, each with two buttons with captions and images.

  • Toolbar1 has the TBSTYLE_FLAT applied. 
  • ToolBar2 retains the default VB toolbar styles - no API code was applied. 
  • Toolbar3, like Toolbar1, has the TBSTYLE_FLAT style and, in addition, the TBSTYLE_LIST style.
  • Toolbar4 has only the TBSTYLE_LIST style applied.

All captions shown were set on the respective toolbar's Button property page.

Typically, assignment of a new caption to a toolbar button is through a simple statement along the lines of:

Toolbar1.Buttons(1).Caption = "Go Backwards"
Toolbar2.Buttons(1).Caption = "Go Backwards"
Toolbar3.Buttons(1).Caption = "Go Backwards"
Toolbar4.Buttons(1).Caption = "Go Backwards"

But when this method of assigning captions is used with the Visual Basic 5 comctl32.ocx control on systems running IE5, in either VB5 or VB6, the resulting toolbars look as shown in illustration two.

Those toolbars having the TBSTYLE_FLAT style dropped all captions, and in doing so caused a vertical resizing as well (as shown through the positioning of the red PhotoShop text).

The desired results can be seen in illustration three, and the code below produces these results.

Briefly, in order to change the caption of a flat toolbar button, under the conditions mentioned, the flat toolbar style must be removed from the toolbar(s), the caption change made, the toolbar refreshed to have it recalculate the correct button width, and then the flat style reapplied and the toolbar refreshed once more.

In addition, when button captions are used and the app is first applying the flat style to the toolbar, the toolbar must also have the TBSTYLE_WRAPABLE style applied. And even though Wrapable is available as a toolbar property, on my system at least, the toolbars need the Wrapable property set to False for the controls, and the style set through the API. Thankfully, this style can be removed if it's not desired in the app.

In the code below are three routines ... CreateFlatToolbar (creating Toolbars 1 and 3), CreateHorizontalToolbar (Toolbar4), and SetToolbarCaption (used to change the caption of all toolbar controls). Since you can not be sure of the final operating system components, adoption of methods such as these will assure that the control displays as intended on differing systems.

 BAS Module Code
Place the following code into the general declarations area of a bas module:

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.
Public Const WM_USER As Long = &H400
Public Const TB_SETSTYLE As Long = WM_USER + 56
Public Const TB_GETSTYLE As Long = WM_USER + 57
Public Const TBSTYLE_WRAPABLE As Long = &H200  'buttons to wrap when form resized
Public Const TBSTYLE_FLAT As Long = &H800      'flat IE3+ style toolbar
Public Const TBSTYLE_LIST As Long = &H1000     'places captions beside buttons

Public Declare Function SendMessage Lib "user32" _
   Alias "SendMessageA" _
  (ByVal hwnd As Long, _
   ByVal wMsg As Long, _
   ByVal wParam As Long, _
   lParam As Any) As Long

Public Declare Function FindWindowEx Lib "user32" _
   Alias "FindWindowExA" _
  (ByVal hWnd1 As Long, _
   ByVal hWnd2 As Long, _
   ByVal lpsz1 As String, _
   ByVal lpsz2 As String) As Long
 Form Code
To the form, add the following code:

Option Explicit

Private Sub Form_Load()

  'centre form
   Me.Move (Screen.Width - Me.Width) \ 2, (Screen.Height - Me.Height) \ 2
  'Under IE5, the toolbars have to be 'visible'
  'before setting to a flat style when the buttons
  'have captions. Failing to 'show' will cause 
  'the button captions to disappear.
  'for the demo, make toolbars 1 and 3 flat
  'args:             ctrl      horiz  wrapable
   CreateFlatToolbar Toolbar1, False, False
   CreateFlatToolbar Toolbar3, True, False
  'set toolbar 4 to horizontal. Since
  'toolbar 2 retains the default
  'appearance, no styles are specified.
  'args:                   ctrl      horiz wrapable
   CreateHorizontalToolbar Toolbar4, True, False

End Sub

Private Sub Command1_Click()
  '                 ctrl,    ndx, caption
  SetToolbarCaption Toolbar1, 1, "Go Backwards"
  SetToolbarCaption Toolbar2, 1, "Go Backwards"
  SetToolbarCaption Toolbar3, 1, "Go Backwards"
  SetToolbarCaption Toolbar4, 1, "Go Backwards"
  'this is the code to produce the illustration 2 results
  'Toolbar1.Buttons(1).Caption = "Go Backwards"
  'Toolbar2.Buttons(1).Caption = "Go Backwards"
  'Toolbar3.Buttons(1).Caption = "Go Backwards"
  'Toolbar4.Buttons(1).Caption = "Go Backwards"
End Sub

Private Sub CreateFlatToolbar(TBar As Toolbar, _
                              fHorizontal As Boolean, _
                              fWrapable As Boolean)

   Dim hTBar As Long
   Dim style As Long
  'to assure that the toolbar has correctly calculated
  'the button widths based on the assigned captions,
  'force a refresh
  'get the handle of the toolbar
   hTBar = FindWindowEx(TBar.hwnd, 0&, "ToolbarWindow32", vbNullString)
  'retrieve the current toolbar style
   style = SendMessage(hTBar, TB_GETSTYLE, 0&, ByVal 0&)
  'Set the new style flags.
  'To assure that the button caption will set the correct
  'button width, the TBSTYLE_WRAPABLE style must be
  'specified before making flat.
  'if a horizontal layout was specified, add that style
   If fHorizontal Then style = style Or TBSTYLE_LIST
  'apply the new style to the toolbar and refresh
   Call SendMessage(hTBar, TB_SETSTYLE, 0&, ByVal style)
  'now that the toolbar is flat, if the wrapable
  'style is not desired, it can be removed.
  'A refresh is not required.
   If fWrapable = False Then
      style = style Xor TBSTYLE_WRAPABLE
      Call SendMessage(hTBar, TB_SETSTYLE, 0&, ByVal style)
   End If
End Sub

Private Sub CreateHorizontalToolbar(TBar As Toolbar, _
                                    fHorizontal As Boolean, _
                                    fWrapable As Boolean)
   Dim hTBar As Long
   Dim style As Long
  'get the handle of the toolbar
   hTBar = FindWindowEx(TBar.hwnd, 0&, "ToolbarWindow32", vbNullString)
  'retrieve the current toolbar style
   style = SendMessage(hTBar, TB_GETSTYLE, 0&, ByVal 0&)
  'Set the new style flags
   If fHorizontal Then
      style = style Or TBSTYLE_LIST
   End If
   If fWrapable Then
      style = style Or TBSTYLE_WRAPABLE
   End If
  'apply the new style to the toolbar and refresh
   Call SendMessage(hTBar, TB_SETSTYLE, 0&, ByVal style)
End Sub

Private Sub SetToolbarCaption(TBar As Toolbar, _
                              TBIndex As Integer, _
                              newCaption As String)
   Dim hTBar As Long
   Dim inStyle As Long
   Dim tempStyle As Long
  'get the handle to the toolbar and its current style
   hTBar = FindWindowEx(TBar.hwnd, 0&, "ToolbarWindow32", vbNullString)
   inStyle = SendMessage(hTBar, TB_GETSTYLE, 0&, ByVal 0&)
  'if the toolbar has had the flat style applied
   If inStyle And TBSTYLE_FLAT Then
     'This will all happen too quickly to
     'reshow the old raised style
     'temporarily remove the flat style
      tempStyle = inStyle Xor TBSTYLE_FLAT
      Call SendMessage(hTBar, TB_SETSTYLE, 0&, ByVal tempStyle)
     'change and refresh the caption. A refresh
     'is required here (before resetting to flat)
     'for the toolbar to recalculate the correct
     'sizes of the toolbar buttons based on the
     'longest item.
      TBar.Buttons(TBIndex).Caption = newCaption
     'restore the previous style, and refresh once more
      Call SendMessage(hTBar, TB_SETSTYLE, 0&, ByVal inStyle)
     'it's not flat, so just change the text
      TBar.Buttons(TBIndex).Caption = newCaption
   End If

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