Link to home
Start Free TrialLog in
Avatar of c_sh
c_shFlag for India

asked on

How does OnAction property works ??

Hi,

I am designing a Addin for outlook that has a custom menuitem suppose, "MyMenuItem". I have added this new menu item and capturing the events by getting the reference of the new menuitem in a global variable "fMenuItem" declared as
Dim WithEvents fMenuItem As Office.CommandBarButton

Everything works fine if I am having a single window opened in an Outlook session. Now the problem arrises when new windows are opened, for example by double clicking the selected e-mail. At this point, a new instance of menu is created and keeping the reference of new one will loose the old refernce.

To sort out this I tried using OnAction property of CommandBarControl object. But unfortunatrly this is not working, I mean the function/sub specified for OnAction is not being invoked by clicking the menu item.

Can anybody help me sorting out this problem?

I have following code:

Dim cbCtrl As CommandBarControl  
Dim cmdControl As CommandBarControl
Dim cbBtn As Office.CommandBarButton  

....
....

    ' add stop MyMenuItem
    With cmdControl
      Set cbCtrl = .Controls.Add(Type:=msoControlButton, Temporary:=True, Before:=2)
      Set cbBtn = cbCtrl

      With cbBtn
        .Style = msoButtonIconAndCaption
        .FaceId = 228
      End With

      With cbCtrl
         .Caption = "MyMenuItem"
         .Tag = .Caption
         .ToolTipText = "This is MyMenuItem :-) "
         .OnAction = "runme"
      End With
   End With


Sub runme()
    MsgBox " Run me called "
End Sub

----------------------------------------

In summary the question is:
- I have menu Item Tools->MyMenuItem.
- This menu item is added to all the newly opened windows from withen the outlook session.
- I have to capture events from all the "MyMenuItem"
- How can this task be done?

:-)
Waiting for suggestions...
c_sh

Avatar of c_sh
c_sh
Flag of India image

ASKER

Opps, forgot to give appropriate ranking !
Avatar of WolfgangKoenig
WolfgangKoenig

Hi

i think the problem is in which outlook menu you hang in your button. Try to add your button to the MenuBar 'Standard' and your button should be always present when this menubar is active.

Hope this helps you ;)
WoK
Avatar of c_sh

ASKER

Hi Wolf :-)
 
I am adding this new menu item in "Tools" menu. I think if I'll add a button on 'Standard' command bar, there will be same problem.
To add the item first time, I have written the code in OnConnection() function of the addin. Now to add my custom menu item or tool button in every new window, I have to catch the event, whenever the new window (explorer object) is created. This is done by executing the same piece of code used in OnConnection().

The problem will still persis.
Hope I am not going in the wrong direction !

c_sh.

This article shows how to use the OnAction properly for com addins:

http://support.microsoft.com/default.aspx?scid=kb;en-us;q238228

Avatar of c_sh

ASKER

aeklund,

Thanks for URL, I have already checked this and I am still not able to find solution for my problem.

I have to capture events from "Tools->MyMenuItem" placed in all the opend windows. The sample works fine if this is placed in single window and NO new window is opened, and unfortunately OnAction property is not working :-( otherwise it'll solve my problem
Sorry i havent't understood your q.
Your problem is that you loose your reference to the button ?!

Check if for every new window the OnConnection routine is
called. If this is the case yiu can use the AddInINst Object to decide what instance created your button.

Hold a references to your buttons in a collection.
=>
DIm MyButtonCollection As New Collection
DIm MyInstCollection As New Collection
DIm InstCounter As Long

..
Set cbCtrl = .Controls.Add(Type:=msoControlButton, Temporary:=True, Before:=2)
Set cbBtn = cbCtrl

MyButtonCollection.Add cbBtn
MyInstCollection.Add AddInINst

..
..

Sub runme()
   MsgBox " Run me called "
End Sub

Now you can check in the method runme which instance
called you button and you hold references to all your buttons.

for instance Window 10:
MyButtonCollection(10) and MyInstCollection.Add

WoK
last line should be:
MyButtonCollection(10) and MyInstCollection(10)
;)
Avatar of c_sh

ASKER

WoK,

I am refering "New window" to one which we get on double clicking the selected mail and this NOT the new instance of Outlook, so OnConnection is invoked just once. Anyway I am able to detect whenever a new window is invoked.

Further, at present I am having the reference of CommandBarControl in a variable declared "With Events". If I'll put the buttons in a collection will i be able to capture the events on them?

c_sh.

Hi C_sh

Yes the references to the button will be exists in the collection, because what you hold in the collection
are only references and not objects (instances).

Through the "MyButtonCollection" you can access them
by:
MyButtonCollection(CurrentWindowIndex)

In your method runme you must read out the CurrentWindowIndex to determine which button of which
window is pressed.

Hope this is the solution ;)
WoK
Hi C_sh
if this doesn't help you can email your zipped code to:
wolf_koenig@gmx.de

then i can see what happens.

WoK
Avatar of c_sh

ASKER

WoK,

I agree that the collection will contatin the references but I have a confusion, whenever we have to catch events of a button we delare something as ...

Dim WithEvents x as CommandBarContorl

So, if I am using a collection to store the buttns, how will I use "With events" and how the click events can be captured?

c_sh
Hi c_sh

In this case all buttons have the "same" click event methods but you can vary them by determining the context
of the routine. For instance:

  With cbCtrl
     .Caption = "MyMenuItem"
' !!-->>
     .Tag = CurrentWindowIndex
' !!<<--
     .ToolTipText = "This is MyMenuItem :-) "
      .OnAction = "runme"
  End With

Now if the method runme() is invoked you can check in which window the button is called:

Sub runme()
   If Me.Tag = 10 Then
     MsgBox("Button in window nr. 10 is pressed!")
   End if
End Sub

This example don't need a collection. But what i don't
know which routine is called when an new button is created
in the new window which is open when you pressed email or
something. In this method you must overwrite the .Tag property of the newly created button to separate them from
the other button. Then you must only check the .Tag attrib and so you know which button in which window is pressed.

WoK
Avatar of c_sh

ASKER

Wok,

my basic problem is that method specified for .OnAction is not being invoked. if this can be done, I think the problem will be solved.

 cbCtrl.OnAction = "runme"

Now clicking on the button "runme" is not invoked.

c_sh.
Hi C_sh :)

Oh yes this can be... You should't define the method by yourself instead of let the reflection do this task for you! The resulting method which you would gain looks like this:

'Declare the button:
Dim cbBtn As Office.CommandBarButton  
...

' Call the reflection and the method that will be created for you should look like this:

Private Sub cbBtn_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
' Beside Ctrl is the ref. to your button
End Sub

WoK
Avatar of c_sh

ASKER

do u mean, I have to give something like this,

...
  .OnAction = "cbBtn_Click"

so that Sub cbBtn_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
can be invoked on usrs's click ?

 


ASKER CERTIFIED SOLUTION
Avatar of WolfgangKoenig
WolfgangKoenig

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of c_sh

ASKER

Wok,

Now I think, I have got the point ! Seems that this will do the required job.
I really appreciate you effort for helping me in this problem.

:-)
Thanks,
c_sh.
C-Sh

Thanks for your points ;)

WoK