[AccessD] CommandBarControl subitems

Seth Galitzer sgsax at ksu.edu
Mon Apr 7 15:40:36 CDT 2003


CommandBars are very strange beasts.  I ran into some strange stuff when
I converted the ErrorHandler to A2K VBE.  I wanted a submenu off of the
Add-Ins menu, and then several items off that submenu.  It turns out a
submenu is handled slightly differently than a parent menu.  It also
turns out that the object model treats commandbars and toolbars almost
exactly the same, and they are both treated as controls.  Note the
CommandBarControl object has a FindControl method.  Here's some of the
code from the ErroHandler add-in to demonstrate this:

Private Function CBDoesCBCtlExist(strCBarName As String, _
	strCtlName As String) As Boolean
    Dim ctl As CommandBarControl
    
    Set ctl = appCurrent.CommandBars(strCBarName).FindControl(, , _
	strCtlName)
    If ctl Is Nothing Then
        CBDoesCBCtlExist = False
    Else
        CBDoesCBCtlExist = True
    End If
    
End Function

This function is a variation on that found in the ODE samples library,
which looks like this:

Private Function CBDoesCBExist(strCBarName As String) As Boolean

    Dim cbrBar As CommandBar
    
    On Error Resume Next
    
    Set cbrBar = appCurrent.CommandBars(strCBarName)
    If Err = 0 Then
        CBDoesCBExist = True
    Else
        CBDoesCBExist = False
    End If
End Function

I used both in various places, although both are probably not needed. 
When initializing the whole thing, I create both the add-in submenu and
the toolbar first, and then add sub-items later.  Here's the code for
that:

Public Const conMenuName = "Add-Ins"
Public Const conSubMenuName = "C2DbFrameWizMenu"
Public Const conTBarName = "C2DbFrameWiz"

Function InitCommandBars() As Boolean
    Dim cbrMenu As CommandBar
    Dim cbrTbar As CommandBar
    Dim ctlCBarCtl As Office.CommandBarControl
    
    'Set up the toolbar first
    If CBDoesCBExist(conTBarName) = False Then
        Set cbrTbar = appCurrent.CommandBars.Add(conTBarName)
        cbrTbar.Position = msoBarTop
        cbrTbar.Visible = True
    End If

    'Set up the Add-in submenu next
    On Error Resume Next
    Set cbrMenu = appCurrent.CommandBars(conMenuName)
    Set ctlCBarCtl = cbrMenu.Controls(conSubMenuName)
    If Err <> 0 Then
        Err.Clear
        Set ctlSubMenu = cbrMenu.Controls.Add(msoControlPopup)
        ctlSubMenu.Caption = "&" & conTBarName
    End If
    
    If Err = 0 Then InitCommandBars = True Else InitCommandBars = False

End Function

Note that in this case, appCurrent is a global pointer to the current
instance of the VBIDE object.  If you just want it for Access, I think
you can just use the built-in Application object.

So once the "parent" commandbars are initialized, I add the menu items
using the following code:

Function AddCommandBarControl(strCommandBarName As String, _
    strControlName As String, strControlCaption As String, _
    strAction As String, intResBitmap As Integer, _
    Optional bAddToSubMenu As Boolean = False, _
    Optional lngType As Long = 1, Optional lngStyle As Long = 3, _
    Optional strShortcut As String = "") As Office.CommandBarButton
    
 On Error Resume Next
 
    Dim cbrNew          As Object
    Dim ctlCBarControl  As Office.CommandBarButton
    
    ' Toolbars are handled slightly differently from menubars,
    '   so set a parent object here
    If bAddToSubMenu Then
        Set cbrNew = ctlSubMenu
    Else
        Set cbrNew = appCurrent.CommandBars(strCommandBarName)
    End If
    
    ' Only add the control if it's not there already
    If CBDoesCBCtlExist(strCommandBarName, strControlName) = False Then
        With cbrNew
            Clipboard.SetData LoadResPicture(intResBitmap, _
		vbResBitmap), vbCFBitmap
            Set ctlCBarControl = .Controls.Add(lngType)
            With ctlCBarControl
                .Tag = strControlName
                .Caption = strControlCaption
                .PasteFace
                .Style = lngStyle
                .OnAction = strAction
                If Len(strShortcut) > 0 Then .ShortcutText = strShortcut
            End With
        End With
    End If
    
    Set AddCommandBarControl = ctlCBarControl
    
End Function

The Init function andt his function are called when the add-in is
activated (when the VBE IDE starts up).  Here's an excerpt from that:

' Constants for characters surrounding ProgID.
Public Const PROG_ID_START As String = "!<"
Public Const PROG_ID_END As String = ">"

If InitCommandBars Then         'If we were successful in creating the commandbars
   'Create the error handler toolbar buttons
    Set ctlTBarErrHndlrEvents = AddCommandBarControl(conTBarName, _
       "ErrHndlrBldr", "&Error Handler", PROG_ID_START & _
       AddInInst.ProgId & PROG_ID_END, conResBmpErr)
' skip a bunch more of these

   'Create the error handler menu bar selection
    Set ctlMenuErrHndlrEvents = AddCommandBarControl( _
        conSubMenuName, "ErrHndlrBldrMenu", "&Error Handler", _
        PROG_ID_START & AddInInst.ProgId & PROG_ID_END, _
        conResBmpErr, True, , , "Ctrl+Shift+Z")
' skip a bunch more of these
End If

Some of this isn't totally relevant, but I hope it will give you an idea
of what's involved at the level of creating commandbars and commandbar
items.

Seth

On Mon, 2003-04-07 at 14:47, Susan Harkins wrote:
> If a CommandBarControl on a menu bar contains submenus, how do I cycle
> through that control's collection to list the submenus? This is driving me
> nuts -- I can't figure out how to reference a control's Collection -- does a
> control have a collection? I'm assuming it does if there are submenus?????
> 
> 
> Dim cbarMenu As CommandBar
>   Dim cbarControl As CommandBarControl
>   Dim cbarSub As CommandBarControl
>   'Dim cbarcolControls As CommandBarControls
>   Set cbarMenu = CommandBars(barname)
>   For Each cbarControl In cbarMenu.Controls
>     If cbarControl.Id = controlname Then
>       For Each control in cbarControl's collection...
> 
> 
> This is where I get lost -- at this point, I need to declare cbarControl's
> collection, and I can't get it.
> 
> 
> Susan H.
> 

-- 
Seth Galitzer			sgsax at ksu.edu
Computing Specialist		http://puma.agron.ksu.edu/~sgsax
Dept. of Plant Pathology
Kansas State University



More information about the AccessD mailing list