UIObject Menu Items with VSTO SE

J

John

Hi there,

I've been trying this for days now.........I'm trying to add a simple menu
item at the bottom of the Tools menu using the UIObject and deployed using
VSTO SE, however I'm having rather intermitent success. It appears ok (is
visible) if there are no existing CustomMenus and it uses the BuiltIn copy,
but if it finds the CustomMenus object and then trys to clone it, it fails
to become visible. I say visible, because I can see it using Graham
Wideman's UIObject Browser tool under all circumstances.

I know I can use the CommandBars model instead but I'm intending to make Doc
level UI changes later on and so would like to stick with the UIObject if at
all possible. Has anyone else managed to use the UIObject with VSTO (I'm
only talking Debug mode at the moment)?

Any feedback would be gratefully accepted. Please find code (adapted from
Graham's book), which I've squeezed into the ThisAddIn code for simplicity
for the time being.

Best regards

John

(Current setup - Visio 2007 Pro / VS 2005 Pro / VSTO SE)


public class ThisAddIn

Private Sub ThisAddIn_Startup(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Startup

AddTestUIMenuItem

End Sub

Private Sub ThisAddIn_Shutdown(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Shutdown

RemoveTestUIMenuItem

End Sub

Private Sub AddTestUIMenuItem()

'-------------------------------------------

Dim UIObj As Visio.UIObject = Nothing

Dim NoDocsMenuSet As Visio.MenuSet = Nothing

Dim AMenu As Visio.Menu = Nothing

Dim AMenuItem As Visio.MenuItem = Nothing

Dim x As Integer

UIObj = GetMostCustomMenus()

' Get the No Docs context menuset

NoDocsMenuSet = UIObj.MenuSets.ItemAtID( _

Visio.VisUIObjSets.visUIObjSetNoDocument)

' Get the 'Tools' menu reference

For x = 0 To NoDocsMenuSet.Menus.Count - 1

If NoDocsMenuSet.Menus.Item(x).Caption = "&Tools" Then

AMenu = NoDocsMenuSet.Menus.Item(x)

Exit For

End If

Next

If (Not AMenu Is Nothing) Then

AMenuItem = AMenu.MenuItems.AddAt(AMenu.MenuItems.Count)

AMenuItem.Caption = "A Test Menu Item"

' Put Menus in place

Me.Application.SetCustomMenus(UIObj)

UIObj.UpdateUI()

End If

End Sub

'-------------------------------------------

Private Sub RemoveTestUIMenuItem()

'-------------------------------------------

Dim UIObj As Visio.UIObject = Nothing

Dim NoDocsMenuSet As Visio.MenuSet = Nothing

Dim AMenu As Visio.Menu = Nothing

Dim i As Integer

UIObj = GetMostCustomMenus()

If Not UIObj Is Nothing Then

' Get the Drawing context menuset

NoDocsMenuSet = UIObj.MenuSets.ItemAtID( _

Visio.VisUIObjSets.visUIObjSetNoDocument)

' Get the 'Tools' menu reference

For i = 0 To NoDocsMenuSet.Menus.Count - 1

If NoDocsMenuSet.Menus.Item(i).Caption = "&Tools" Then

AMenu = NoDocsMenuSet.Menus.Item(i)

Exit For

End If

Next

If (Not AMenu Is Nothing) Then

For i = AMenu.MenuItems.Count - 1 To 0 Step -1

If AMenu.MenuItems(i).Caption = "A Test Menu Item" Then

System.Diagnostics.Debug.WriteLine( _

AMenu.MenuItems(i).Caption)

AMenu.MenuItems(i).Delete()

' Put updated UIObject in place

Me.Application.SetCustomMenus(UIObj)

UIObj.UpdateUI()

Exit For

End If

Next

Else

'AMenu Is Nothing

End If

End If

End Sub

'-------------------------------------------

Private Function GetMostCustomMenus() As Visio.UIObject

'-------------------------------------------

' Only looks at App.Builtin and App.Custom as menu is

' added at application startup and so no docs exist

Dim UIObj As Visio.UIObject = Nothing

'On Error Resume Next

If Not Me.Application.CustomMenus Is Nothing Then

UIObj = Me.Application.CustomMenus.Clone

UIObj.Name = "FromCustom"

'System.Diagnostics.Debug.WriteLine("App custom menu is nothing")

End If

If UIObj Is Nothing Then

UIObj = Me.Application.BuiltInMenus

UIObj.Name = "FromBuiltIn"

End If

System.Diagnostics.Debug.WriteLine(UIObj.Name)

GetMostCustomMenus = UIObj

End Function

End class
 
P

Paul Herber

Hi there,

I've been trying this for days now.........I'm trying to add a simple menu
item at the bottom of the Tools menu using the UIObject and deployed using
VSTO SE, however I'm having rather intermitent success. It appears ok (is
visible) if there are no existing CustomMenus and it uses the BuiltIn copy,
but if it finds the CustomMenus object and then trys to clone it, it fails
to become visible. I say visible, because I can see it using Graham
Wideman's UIObject Browser tool under all circumstances.

I know I can use the CommandBars model instead but I'm intending to make Doc
level UI changes later on and so would like to stick with the UIObject if at
all possible. Has anyone else managed to use the UIObject with VSTO (I'm
only talking Debug mode at the moment)?

Hi John,
It's Delphi code but I hope you understand it :

http://www.delphi-code.sandrila.co.uk/visio/add_menu.php

I had a similar problem when implementing multiple add-ons, there
seems to be a race condition for getting hold of and modifying the
menus.
The above code makes it better, not 100% though.

There are certainly conditions when the builtin menu returns a nil
pointer.
And (I'm guessing here) if two add-ons both try to modify the menus
then even if both check the custom menu pointer and find a nil
pointer, one of the add ons may already be in the process of creating
a cloned menu.
 
J

John

Hello Paul,

Thanks very much for your reply. I change the Get UIObject function (see
below) based on your code, but I'm still getting similar results (ie it
loads into the menuset as can be seen in the UIObject Browser but isn't
visible to the user. I've also added a counter which shows that it's not
encountering a App.BuiltinMenus Is Nothing situation.

Any other thoughts?

Thanks again

John


Private Function GetMostCustomMenus() As Visio.UIObject

'-------------------------------------------

' Only looks at App.Builtin and App.Custom as menu is

' added at application startup and so no docs exist

Dim UIObj As Visio.UIObject = Nothing

Dim AppReady As Boolean = False

Dim iCnt as Integer = 0

' wait for any startup dialogs to finish

Do While AppReady = False

iCnt = iCnt + 1

'if the builtin menu is unavailable then Visio must be busy

If Not Me.Application.BuiltInMenus Is Nothing Then

AppReady = True

Else

'Let Visio do its stuff

Me.Application.DoEvents()

End If

Loop

System.Diagnostics.Debug.WriteLine("Wait loops = " & iCnt.ToString)

'On Error Resume Next

If Not Me.Application.CustomMenus Is Nothing Then

UIObj = Me.Application.CustomMenus.Clone

UIObj.Name = "FromCustom"

End If

If UIObj Is Nothing Then

UIObj = Me.Application.BuiltInMenus

UIObj.Name = "FromBuiltIn"

End If

System.Diagnostics.Debug.WriteLine(UIObj.Name)

GetMostCustomMenus = UIObj

End Function
 
J

John

Hi Paul,

Have continued testing and noticed the following:

1) Behaves correctly if all other COM Addin are disabled.

2) Behaves correctly if Document type COM Addins are enabled such as WBS
Modeller and SDK Flowchart Sample (I assume because they're not trying to
make App level UI changes)

3) Stops working when an App type COM Addin such as Send To Bluetooth is
enabled.

4) Stepping through the code in the above instance (3) shows that the
CustomMenus object appears to be cloned correctly. On running through
App.SetCustomMenus(UIObj) it appears to transfer to the App and the
CustomMenusFile string is changed from custom12.vsu to "". The result is
the same though: visible in the UI Browser but not in the UI itself.

Is there a way of tracking what order the addins are loaded?

Best regards

John


John said:
Hello Paul,

Thanks very much for your reply. I change the Get UIObject function (see
below) based on your code, but I'm still getting similar results (ie it
loads into the menuset as can be seen in the UIObject Browser but isn't
visible to the user. I've also added a counter which shows that it's not
encountering a App.BuiltinMenus Is Nothing situation.

Any other thoughts?

Thanks again

John


Private Function GetMostCustomMenus() As Visio.UIObject

'-------------------------------------------

' Only looks at App.Builtin and App.Custom as menu is

' added at application startup and so no docs exist

Dim UIObj As Visio.UIObject = Nothing

Dim AppReady As Boolean = False

Dim iCnt as Integer = 0

' wait for any startup dialogs to finish

Do While AppReady = False

iCnt = iCnt + 1

'if the builtin menu is unavailable then Visio must be busy

If Not Me.Application.BuiltInMenus Is Nothing Then

AppReady = True

Else

'Let Visio do its stuff

Me.Application.DoEvents()

End If

Loop

System.Diagnostics.Debug.WriteLine("Wait loops = " & iCnt.ToString)

'On Error Resume Next

If Not Me.Application.CustomMenus Is Nothing Then

UIObj = Me.Application.CustomMenus.Clone

UIObj.Name = "FromCustom"

End If

If UIObj Is Nothing Then

UIObj = Me.Application.BuiltInMenus

UIObj.Name = "FromBuiltIn"

End If

System.Diagnostics.Debug.WriteLine(UIObj.Name)

GetMostCustomMenus = UIObj

End Function
 
P

Paul Herber

Hi Paul,

Have continued testing and noticed the following:

1) Behaves correctly if all other COM Addin are disabled.

Some behaviour will depend on how well behaved the other addins are. I
know some of them don't follow the rules.
Would you like to try out
http://www.visio-utilities.sandrila.co.uk/ and try out the software
there to see whether that gives a problem. I know exactly how the
menus work there!
 
J

John

Hi Paul,

Yes, I'm sure you're right about other addins although I'm a little
suspicious about how comfortably the CommandBars model and UIObject sit
together.

Thanks for the offer of your utilities package. I downloaded the zip file
and notice that it's an Add-On rather than a COM Add-in. I've tried
disabling all the other COM Add-ins (leaving the Add-Ons working as normal)
and the menu item performs properly every time, so I think I rather find out
if anyone has actually managed to use the UIObject in a VSTO Add-in, because
if not I may just opt for CommandBars and be done with it!

Thank you very much for the offer though and I've also learnt some Delphi
into the bargain.

Best regards

John
 
P

Paul Herber

Hi Paul,

Yes, I'm sure you're right about other addins although I'm a little
suspicious about how comfortably the CommandBars model and UIObject sit
together.

Thanks for the offer of your utilities package. I downloaded the zip file
and notice that it's an Add-On rather than a COM Add-in. I've tried
disabling all the other COM Add-ins (leaving the Add-Ons working as normal)
and the menu item performs properly every time,

Good, so I think that shows that your menu is working properly. The
other add-ins may not be doing so and may be causing the problem.
 

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