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