Carlos Quintero (Microsoft MVP) blog

Visual Studio Extensibility with Add-ins

November 2009 - Posts

There is a bug/issue that I reported years ago for VS 2005 and was not even acknowledged as a bug but "by design". VS 2010 (Beta 2) still exhibits it so I keep pushing to get if fixed (the original bug report was lost, I think it died when MSDN Product Feedback became Microsoft Connect):

VS 2010 Beta2: importing settings destroys commandbars created by add-ins
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=512214

The problem is that Visual Studio thinks that all the commandbars of the IDE belong to it, ignoring the fact that some commandbars belong to add-ins and it should ignore them when importing settings, rather than resetting them or destroying them...

To complicate things, when the add-in is unloaded at some point later (by the user or closing VS), it doesn't have a direct way to know if its commandbars have been destroyed by Visual Studio, so it tries to delete them and it gets a ObjectDisposedException....

Posted by carlosq | with no comments
Filed under:

In VS 2008 (and previous versions), when you opened the "Tools", "Customize..." dialog, "Commands" tab, you got a list of  "categories", and each category has a list of commands that you could drag and drop on some toolbar to create a button from that command. For commands provided by add-ins, you had the "Add-Ins" category and for commands provided by macros you had the "Macros" category. Furthermore, you had a "Rearrange Commands..." button where a new dialog allowed you to select a menu bar or a toolbar, and add/move/remove commands (buttons), etc. So far so good, except one thing that VS has never managed well which is that toolbars, menu bars, commandbar popups and buttons provided by add-ins can be temporary if the add-in uses that approach instead of the permanent one, and therefore Visual Studio should not offer the temporary UI items of add-ins for customization, since customization will be lost when the add-in is unloaded and when loaded again the add-in will recreate the UI from scratch. I discussed these issues in detail in the article:

HOWTO: Handling buttons and toolbars user customizations from a Visual Studio add-in
http://www.mztools.com/articles/2008/MZ2008019.aspx

In VS 2010 (Beta 2), commandbars are WPF-based and the Customize dialog has suffered a re-design, but if it is not fixed in the RC / RTM builds things are getting worse due to these bugs (currently under evaluation, but likely closed as "won't fix" in this release):

VS 2010 Beta 2 Bug: wrong customization for commandbarpopup of add-ins
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=501255

VS 2010 Beta2: Add-ins and macros commands should not appear in the "Tools", "Customize" dialog, "Commands" tab, "Menu bar" combobox
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=512141

Those bugs will cause confusion to users of add-ins if they try to use the Customize dialog...

At least these two minor bugs were fixed after Beta 2:

VS 2010 Beta 2 Bug: Command picture not shown in Tools, Customize window, Commands tab
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=502250

VS 2010 Beta 2 Bug: Command name shown instead of caption in Tools, Customize window, Commands tab
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=502242

Posted by carlosq | with no comments
Filed under:

This bug eluded me during several days because there was another bug that already caused VS 2010 Beta 2 to hang, but finally a couple of days ago I realized that was seeing a different issue (no commandbarbutton involved in this new bug) and I was able to isolate and report it today:

VS 2010 Beta 2 Bug: adding CommandBarPopup to CommandbarPopup causes VS to hang if CommandBarPopup was added to Toolbar before

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=507650

As I expressed some days ago, my feeling with VS 2010 so far (after four builds) is that once you patch your add-in to (somehow) bypass a bug, the add-in finds a new one.

The (VB.NET) code to reproduce it is:

Imports System
Imports Microsoft.VisualStudio.CommandBars
Imports Extensibility
Imports EnvDTE
Imports EnvDTE80

Public Class Connect
   Implements IDTExtensibility2

   Private _applicationObject As DTE2
   Private _addInInstance As AddIn
   Private _commandBarToolbar As CommandBar
   Private _commandBarPopupOnToolbar As CommandBarPopup
   Private _commandBarPopupMenu As CommandBarPopup
   Private _commandBarPopupOnMenu As CommandBarPopup

   Public Sub OnConnection(ByVal application As Object, ByVal connectMode As ext_ConnectMode, ByVal addInInst As Object, ByRef custom As Array) Implements IDTExtensibility2.OnConnection

      _applicationObject = CType(application, DTE2)
      _addInInstance = CType(addInInst, AddIn)

      Select Case connectMode

         Case ext_ConnectMode.ext_cm_AfterStartup
            InitializeAddIn()

         Case ext_ConnectMode.ext_cm_Startup
            ' OnStartupComplete will be called

      End Select

   End Sub

   Public Sub OnStartupComplete(ByRef custom As Array) Implements IDTExtensibility2.OnStartupComplete
      InitializeAddIn()
   End Sub

   Private Sub InitializeAddIn()

      Dim commandBars As CommandBars

      Try

         commandBars = CType(_applicationObject.CommandBars(), CommandBars)

         If MessageBox.Show("Create toolbar before menu?", "", MessageBoxButtons.YesNo) = DialogResult.Yes Then

            ' This hangs VS 2010 Beta 2
            CreateToolbar(commandBars)
            CreateMenu(commandBars)

         Else

            ' This causes nested menus but doesn't hang VS 2010 Beta 2
            CreateMenu(commandBars)
            CreateToolbar(commandBars)

         End If

      Catch ex As Exception
         System.Windows.Forms.MessageBox.Show(ex.ToString)
      End Try

   End Sub

   Private Sub CreateToolbar(ByVal commandBars As CommandBars)

      _commandBarToolbar = commandBars.Add(Name:="My toolbar", Position:=MsoBarPosition.msoBarTop, Temporary:=True)
      _commandBarPopupOnToolbar = AddCommandBarPopupToCommandBar(_commandBarToolbar, "MyPopupOnToolbar", "My Popup On Toolbar")
      _commandBarToolbar.Visible = True

   End Sub

   Private Sub CreateMenu(ByVal commandBars As CommandBars)

      Dim menuCommandBar As CommandBar

      menuCommandBar = commandBars.Item("MenuBar")

      _commandBarPopupMenu = AddCommandBarPopupToCommandBar(menuCommandBar, "MyPopupMenu", "My Menu")
      _commandBarPopupOnMenu = AddCommandBarPopupToCommandBar(_commandBarPopupMenu.CommandBar, "MyPopupOnMenu", "My Popup On Menu")
      _commandBarPopupMenu.Visible = True

   End Sub

   Public Sub OnDisconnection(ByVal disconnectMode As ext_DisconnectMode, ByRef custom As Array) Implements IDTExtensibility2.OnDisconnection

      Try

         If Not _commandBarPopupOnMenu Is Nothing Then
            _commandBarPopupOnMenu.Delete()
         End If

         If Not _commandBarPopupOnToolbar Is Nothing Then
            _commandBarPopupOnToolbar.Delete()
         End If

         If Not _commandBarPopupMenu Is Nothing Then
            _commandBarPopupMenu.Delete()
         End If

         If Not _commandBarToolbar Is Nothing Then
            _commandBarToolbar.Delete()
         End If

      Catch ex As Exception
         System.Windows.Forms.MessageBox.Show(ex.ToString)
      End Try

   End Sub

   Public Sub OnAddInsUpdate(ByRef custom As Array) Implements IDTExtensibility2.OnAddInsUpdate
   End Sub

   Public Sub OnBeginShutdown(ByRef custom As Array) Implements IDTExtensibility2.OnBeginShutdown
   End Sub

   Friend Shared Function AddCommandBarPopupToCommandBar(ByVal objParentCommandBar As CommandBar, _
 ByVal sCommandBarName As String, ByVal sCaption As String) As CommandBarPopup

      Dim objCommandBarPopup As CommandBarPopup = Nothing
      Dim objCommandBar As CommandBar
      Dim objCommandBarControl As CommandBarControl
      Dim iPosition As Integer

      If Not (objParentCommandBar Is Nothing) Then

         iPosition = objParentCommandBar.Controls.Count + 1

         objCommandBarControl = objParentCommandBar.Controls.Add(Type:=MsoControlType.msoControlPopup, Before:=iPosition)

         objCommandBarPopup = CType(objCommandBarControl, CommandBarPopup)

         objCommandBar = objCommandBarPopup.CommandBar

         If Not (objCommandBar Is Nothing) Then

            objCommandBar.Name = sCommandBarName

            objCommandBarPopup.Caption = sCaption

         End If

      End If

      Return objCommandBarPopup

   End Function

End Class

 

 

Posted by carlosq | with no comments

In the post CommandBarButton.Mask property deprecated in VS 2010 I mentioned that VS 2010 will deprecate the Mask property of CommandBarButton to specify bitmap transparency, accepting 32-bit bitmaps with transparency in the alpha channel in the CommandBarButton.Picture property instead.

The VS team told me some weeks ago that the CommandBarButton.Picture would accept also in next VS 2010 builds 24-bit bitmaps with RGB=0,254,0 (almost pure green) as transparent color (as VS has always accepted for commands). I have verified this week that VS 2010 Beta 2 accepts that possibility correctly.

Bottom line: VS 2010 will accept both in Commands (AddNamedCommand) and CommandBarButton.Picture:

  • 32-bit bitmaps with transparency in the alpha channel
  • 24-bit bitmaps with RGB=0,254,0 (almost pure green) as transparent color
Posted by carlosq | with no comments
Filed under: