Could I use a Button Wrapper Class???

K

Kristy

Hi

I want to use a commandbarpopup on my custom commandbar instead of a
combobox. The problem is that I have a variable number of commands to
add so I can't individually declare them withevents.

I've read a couple of things about creating a button wrapper class and
I've started to look into this.

The commands on the popup in question need to be available to both
explorer and inspector objects so I thought that I could use the
explorer and inspector wrappers that I already have (based on itemscb
example) to instantiate colCBars = Commandbars (declared withevents as
Office.Commandbars). Then hopefully when I am creating my
commandbarbuttons (also declared with events) the colCBars_OnUpdate()
event would fire and I could add each button created to the collection
so that each one would have a click event.

Before I go too much further can anyone tell me if this is even
possible with a commandbarpopup and if so just how you would go about
setting it up :)

Thanks

Kristy
 
K

Ken Slovak - [MVP - Outlook]

Sure it can be done, I've done it for a number of projects where I needed a
variable, dynamic set of menu items added to a menu.

I instantiate a class module that handles the button events just like an
Inspector or Explorer wrapper does for those related events. Similar
declarations and add/remove functions. I make sure each button that's added
has a unique Tag property so only one class sinks events for that specific
button.

There's an Inspector wrapper example you might want to also review at
http://www.slovaktech.com/code_samples.htm#InspectorWrapper
 
K

Kristy

Hi Ken

Thanks, I spent quite a bit of time reviewing your inspector wrapper
last night and have tidied up my wrapper considerably based on
it....thanks.

I am having some difficulty setting up my button wrapper, I'm missing
something important and therefore can't seem to tie everything
together. In clsBtnOutAddin I've declared

colBtn withevents as Office.CommandBars
cbbNewButton withevents as Office.CommandBarButtons
cbpNewButton as Office.commandbarpopup.

This is what I've tried so far...

In my initialisation handler routine I
Set colBtn = olapp.ActiveExplorer.CommandBars.

I though that the following would fire when I created the buttons
(using Add) so that I'd be able to add each button, but it doesn't????

colBtn_OnUpdate()
AddBtn Button
End If

This is the button creation code:

Public Sub CreateButtons(ByVal objFolder As Outlook.MAPIFolder)
Dim sStr As String
Dim sname As String
Dim lLen As Integer
Dim sPath As String

On Error Resume Next
Set cbrMyBar = Outlook.ActiveExplorer.CommandBars("MyBar")

Set cbpNew = cbrMyBar.FindControl(Type:=msoControlPopup, Tag:="New")
If cbpNew Is Nothing Then
Set cbpNew = cbrMyBar.Controls.Add(msoControlPopup, , , , True)
End If
With cbpNew
.Caption = "New"
.Tag = "New"
.BeginGroup = True
End With


'Info to fill popup is obtained frm a UDT

If CustomNew(i).strNew = "" Then
cbpNew.Visible = False
Else
For i = 0 To UBound(CustomNew)
Set cbbNew = cbpNew.Controls.Add(msoControlButton, , ,
, True)

With cbbNew
.Enabled = True
.Visible = True
.Tag = CustomNew(i).
.Caption = CustomNew(i).strNew
.OnAction = "!<" & gstrProgId & ">"
End With
Next
End If
'reset i
i = 0
End Sub

I also have a clsBtnWrap which contains the wrapper code and
basOutlBtn which is a standard module and has the following:

Public gcolBtnWrap As New Collection
Dim nID As Integer
Dim blnActivate As Boolean

Public Function AddBtn(Button As Office.CommandBarButton) As String
Dim objBtnWrap As New BtnWrap
Dim objItem As Object
Dim intClass As Integer

On Error Resume Next
objBtnWrap.Button = Button
objBtnWrap.Key = nID
strID = CStr(nID)
gcolBtnWrap.Add objBtnWrap, strID

AddBtn = strID
nID = nID + 1

If Err <> 0 Then
AddInErr Err
End If

Set objBtnWrap = Nothing
Set objItem = Nothing
End Function

Public Sub KillBtn(anId As Integer, objBtnWrap As BtnWrap)
Dim objBtnWrap2 As BtnWrap

On Error Resume Next
Set objBtnWrap2 = gcolBtnWrap.item(CStr(anId))
If Not objBtnWrap2 Is objBtnWrap Then
Err.Raise 1, Description:="Unexpected Error in KillBtn"
Err.Clear
GoTo CleanUp
End If

gcolBtnWrap.Remove CStr(anId)

CleanUp:

Set objBtnWrap2 = Nothing
End Sub

As you can see I've tried to emulate the insp/expl wrappers as close
as possible, but I'm missing the link between the
commandbar/commandbarpopup and the buttons... can you set me
straight???? Pleeeeeze :)

Kristy
 
K

Ken Slovak - [MVP - Outlook]

When in doubt use the Object Browser. There are no events at all for
CommandBars and there is no "CommandBarButtons" there is only
CommandBarButton.

Add the buttons as needed and use CommandBarButton.Click to respond to the
button click.

CommandBars is all of your menus and toolbars, either for an Inspector or
Explorer. You get a different collection for each. Each menu or toolbar is a
CommandBar. Each CommandBar has a CommandBarControls collection, which
contains all the buttons and menu popups. Ultimately you get down to
buttons, which are the only thing that can fire a click event.

To add a new menu/toolbar add a new CommandBar. To add a menu item that has
a flyout (like File or File, Open...) add a CommandBarPopup. To add a button
to a menu/toolbar add a CommandBarButton. All those are added to the
object.CommandBarControls collection. For a CommandBarPopup use
objPop.CommandBar.Controls.Add to add a new button.

I'll dig up the code to one of my button wrappers either over the weekend or
on Monday and post it in this thread. It will be VB 6 code.
 
K

Kristy

Thanks Ken... a button wrapper example in vb6 is exactly what I
need... you've saved my life :)


Kris
 
K

Ken Slovak - [MVP - Outlook]

Here's a little explanation of what this code is doing. Your initialization
may be somewhat different.

In this case an INI file is located on a network share. The INI file has a
list of Word templates that can be opened from an Outlook menu. The
templates are filled with Outlook data. The INI file is read when the addin
initializes. At that point a new menu item is created for each template
listed in the INI file.

The code that creates the buttons (menu items) in a basCommandBars code
module:

Public Function AddTemplateButtons(objBarButton As Office.CommandBarControl)
Dim i As Long
Dim j As Long
Dim lControlsCount As Long
Dim lUbound As Long
Dim lLBound As Long
Dim sname As String
Dim sLocation As String
Dim blnBeginGroup As Boolean
Dim lBegin As Long
Dim intTag As Integer
Dim sTag As String
Dim sID As String
Dim objButton As Office.CommandBarButton
Dim objOldButton As Office.CommandBarButton
Dim objPopup As Office.CommandBarPopup
Dim clsWrapper As clsButtonWrap
Dim blnFound As Boolean

On Error Resume Next

Set objPopup = objBarButton
lControlsCount = objPopup.Controls.Count

If lControlsCount > 3 Then
For i = lControlsCount To 4 Step -1
objPopup.Controls.Item(i).Delete
Next i
End If

lBegin = 0

lUbound = UBound(g_strTemplateDisplayName)
lLBound = LBound(g_strTemplateDisplayName)

For i = lLBound To lUbound
blnFound = False
blnBeginGroup = False
sname = g_strTemplateDisplayName(i)
sLocation = g_strTemplateLocation(i)
If sname <> "" Then
For j = 1 To objPopup.Controls.Count
Set objOldButton = objPopup.Controls.Item(j)
If objOldButton.Caption = sname Then
blnFound = True
Exit For
End If
Next j

If Not blnFound Then
If lBegin = 0 Then
blnBeginGroup = True
lBegin = 1
End If

intTag = basOutlButton.GetNextButtonID
sTag = sname & CStr(intTag)
Set objButton = CreateAddInCommandBarButton(gstrProgID, _
objBarButton, sname, sTag, "Merge selected contacts to template",
_
blnBeginGroup, msoButtonCaption)

If Not objButton Is Nothing Then
sID = basOutlButton.AddButton(objButton)
Set clsWrapper = gcolButtonWrap.Item(sID)
clsWrapper.Name = sname
clsWrapper.Location = sLocation
End If
End If
End If
Next i

Set objOldButton = Nothing
Set objButton = Nothing
Set clsWrapper = Nothing
Set objPopup = Nothing

Err.Clear
End Function

Public Function CreateAddInCommandBarButton _
(strProgID As String, objCommandBar As Office.CommandBarPopup, _
strCaption As String, strTag As String, strTip As String, _
blnBeginGroup As Boolean, intStyle As Integer) _
As Office.CommandBarButton

Dim ctlBtnAddin As CommandBarButton
Dim oCB As Office.CommandBar

On Error Resume Next

' Test to determine if button exists on command bar.
Set oCB = objCommandBar.CommandBar
Set ctlBtnAddin = oCB.FindControl(Tag:=strTag)
If ctlBtnAddin Is Nothing Then
' Add new button.
Set ctlBtnAddin = oCB.Controls.Add(Type:=msoControlButton, _
Parameter:=strTag)
' Set button's Caption, Tag, Style, and OnAction properties.
With ctlBtnAddin
.Caption = strCaption
.Tag = strTag
.Style = intStyle
.ToolTipText = strTip
.BeginGroup = blnBeginGroup
' Set the OnAction property with ProgID of Add-In
.OnAction = "<!" & strProgID & ">"
End With
End If

' Return reference to new commandbar button.
Set CreateAddInCommandBarButton = ctlBtnAddin

Set ctlBtnAddin = Nothing
Set oCB = Nothing
End Function

The code in basOutlButton, which is also a code module that adds and removes
the button classes from a wrapper collection. gcolButtonWrap is a global
level collection variable to hold the wrapper classes:

Dim intID As Integer
Dim blnActivate As Boolean

Public Function GetNextButtonID() As Integer
On Error Resume Next
GetNextButtonID = intID
Err.Clear
End Function

Public Function AddButton(Button As Office.CommandBarButton) As String
Dim objButtonWrap As New clsButtonWrap
Dim strID As String

On Error Resume Next

objButtonWrap.Button = Button

objButtonWrap.Key = intID
strID = CStr(intID)
gcolButtonWrap.Add objButtonWrap, strID

AddButton = strID

intID = intID + 1

Set objButtonWrap = Nothing
Err.Clear
End Function

Public Sub KillButton(intID As Integer, objButtonWrap As clsButtonWrap)
Dim objButtonWrap2 As clsButtonWrap

On Error Resume Next

Set objButtonWrap2 = gcolButtonWrap.Item(CStr(intID))
' checks to make sure we're removing the
' right Button from the collection
If Not objButtonWrap2 Is objButtonWrap Then
LogAddInErr Err, "basOutlButton", "KillButton", "Unexpected Error in
KillButton"
Else
gcolButtonWrap.Remove CStr(intID)
End If

Set objButtonWrap2 = Nothing
Err.Clear
End Sub

clsButtonWrap is the wrapper class module:

Private WithEvents m_objButton As Office.CommandBarButton

Private m_intID As Integer
Private m_strLocation As String
Private m_strName As String

Private Sub Class_Initialize()
On Error Resume Next
Set m_objButton = Nothing
Err.Clear
End Sub

Private Sub Class_Terminate()
On Error Resume Next
Set m_objButton = Nothing
Err.Clear
End Sub

Public Property Let Button(objButton As Office.CommandBarButton)
On Error Resume Next
Set m_objButton = objButton
Err.Clear
End Property

Public Property Get Button() As Office.CommandBarButton
On Error Resume Next
Set Button = m_objButton
Err.Clear
End Property

Public Property Let Location(strLocation As String)
On Error Resume Next
m_strLocation = strLocation
Err.Clear
End Property

Public Property Get Location() As String
On Error Resume Next
Location = m_strLocation
Err.Clear
End Property

Public Property Let Name(strName As String)
On Error Resume Next
m_strName = strName
Err.Clear
End Property

Public Property Get Name() As String
On Error Resume Next
Name = m_strName
Err.Clear
End Property

Public Property Let Key(intID As Integer)
On Error Resume Next
m_intID = intID
Err.Clear
End Property

Public Property Get Key() As Integer
On Error Resume Next
Key = m_intID
Err.Clear
End Property

Private Sub m_objButton_Click(ByVal Ctrl As Office.CommandBarButton,
CancelDefault As Boolean)
Dim blnResult As Boolean

On Error Resume Next

blnResult = MergeToTemplate(m_strLocation)

Err.Clear
End Sub
 
K

Kristy

Words cannot express how happy I am! Thank you so much Ken, it works
beautifully :)

Kris
 
K

Ken Slovak - [MVP - Outlook]

Glad I could help :)

I suppose I should post that and some of my other wrappers on my Web site
one of these days. I put the Inspector wrapper up there but should add some
others.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top