KnowDotNet NetRefactor

Context Menus in a Visual Studio .NET Add-in

by Les Smith
Print this Article Discuss in Forums

How do I create a new popup menu item on a Visual Studio .NET IDE context menu?  For example, I want to add a popup menu item to the code window context menu, and then add menu items to my popup menu.  First, you cannot use the AddNamedCommand method that is generated by the Add-in Wizard.  That method will only add menu items to an existing popup menu.  Instead, you must use a Microsoft Office Command objects and methods.  This article will show the code for adding a new system of menus to an IDE context menu.

First, in the declaration section of the add-ins Connect class, you need to dimension some objects, as follows.  The first two CommandBar objects will be used for two different purposes.  The first will be used for the Code Window when nothing is selected.  The second will be used when you have a control selected in the Form Designer window.  The third will be used to add a popup menu to the IDE's Tools Menu.

   Dim cmdBarCW As Microsoft.Office.Core.CommandBar
  
Dim cmdBarFD As Microsoft.Office.Core.CommandBar
  
Dim cmdBarTools As Microsoft.Office.Core.CommandBar

Next, dimension a CommandBarPopup object that will be used to create the popup menu.  Also, you need to provide a event handler for the popup menu, which is done with the WithEvents statement.

   Dim popCommentMenu As Microsoft.Office.Core.CommandBarPopup
  
Public WithEvents popCommentMenuHandler As EnvDTE.CommandBarEvents

Now, dimension the sub menu items and their event handlers.  Having done this, you can now go to the object drop down list on the left top of the code window, click on the mnuBlockCommentHandler. Now go to the method drop down list on the right side of the code window, and click the Click event.  That will cause VB to create an event handler Sub routine for the popCommentMenu click events.  You will need to repeat this process for each of the sub menu handlers, so that they all have event sub routines.

   ' menuitems for comment popup
   Dim mnuBlockComment As Microsoft.Office.Core.CommandBarControl
  
Public WithEvents mnuBlockCommentHandler As EnvDTE.CommandBarEvents
  
Dim mnuBlockAddition As Microsoft.Office.Core.CommandBarControl
  
Public WithEvents mnuBlockAdditionHandler As EnvDTE.CommandBarEvents

When you click on the "Click" event, as described above, the following Sub method will be created.  You will need to place your code for processing the event in the method.  You will find this code generated at the bottom of the Connect class code window.

   Private Sub mnuBlockCommentHandler_Click(ByVal _
      CommandBarControl
As Object, _
      
ByRef handled As Boolean, _
      
ByRef CancelDefault As Boolean) _
      
Handles mnuBlockCommentHandler.Click
  
End Sub

Finally, the code for adding the menus to the existing IDE popup menus can be shown.  I would normally handle the following code in a method, but since I have such a simple example, I will simply give you the required code snippets to create the menus previously described.  The following code adds the command bar popup menu objects to the respective IDE command popup windows.  

If you are wondering where the names "Code Window" and "Selection" come from.  On the Microsoft site, you can search for Automation Samples.   When you find that page, you will see an add-in sample named "CmdBrowser".  You can download that sample add-in, build, install and run it to see a list of all the Commands and Menus in the IDE.  It just so happens that the Code Window popup menu can be referenced by the string "Code Window".   When a control is selected on a Form in the designer window, you can reference the popup by the string "Selection".  Obviously, there is a name for each of the popup menus in the IDE.  If you need to find the name of other context or tool windows, I suggest you download and run the CmdBrowser add-in previously mentioned.

   ' set up tools/codewindow menu ptr
   cmdBarCW = oVB.CommandBars("Code Window")
   cmdBarTools = oVB.CommandBars("Tools")
   cmdBarFD = oVB.CommandBars("Selection")

The code shown below creates a popup menu and sets its caption to the text that you want to see displayed in your new popup menu.  You will now have a popup to which you can add sub menu items.

   popCommentMenu =
      cmdBarCW.Controls.Add(MsoControlType.msoControlPopup, _
      System.Reflection.Missing.Value, _
      System.Reflection.Missing.Value, _
      Before:=1, Temporary:=
True)
   popCommentMenu.Caption = "My Comment Options"

Now that you have added your popup menu, the code shown below will add two sub menus to the newly created popup menu.  After each sub menu item is added to the popup menu, the next line of code sinks the handler for the respective menu item.

   ' create comment menu items and sink the event handler
   mnuBlockComment = _
      AddOfficeMenuItem(popCommentMenu, "Block Comment")
   mnuBlockCommentHandler = _
      
CType(oVB.Events.CommandBarEvents(mnuBlockComment), _
      EnvDTE.CommandBarEvents)

   mnuBlockAddition = _
      AddOfficeMenuItem(popCommentMenu, "Block Addition")
   mnuBlockAdditionHandler = _
      
CType(oVB.Events.CommandBarEvents(mnuBlockAddition), _
      EnvDTE.CommandBarEvents)


The code, shown above, calls a method that I have written to handle the addition of the menu items.  That method is shown as follows.  I have not chosen to add bitmaps to the sub menu items, but this method will do that if you pass a bitmap object into the method.  

   ' This method will add an office menuitem to an existing
   ' office popupup menu
   Public Function AddOfficeMenuItem(ByVal _
      Menu
As Microsoft.Office.Core.CommandBarControl, _
      
ByVal Caption As String, _
      
Optional ByVal pos As Byte = 0, _
      
Optional ByVal sep As Boolean = False, _
      
Optional ByVal Bitmap As Object = Nothing) _
      
As Microsoft.Office.Core.CommandBarControl

      
Dim menuItem As Microsoft.Office.Core.CommandBarControl

      
Try
         If Not (Bitmap Is Nothing) Then
            System.Windows.Forms.Clipboard.SetDataObject(Bitmap)
        
End If

         ' Add menu item to VB menu:
         If pos = 0 Then pos = Menu.Controls.Count + 1
         menuItem = _
            Menu.Controls.Add(Type:= _
            Microsoft.Office.Core.MsoControlType.msoControlButton, _
            Before:=pos, _
            Temporary:=
True)

        
' Set properties of menu item:
         menuItem.Caption = Caption
        
If sep Then menuItem.BeginGroup = True
         If Not (Bitmap Is Nothing) Then
            menuItem.Style = _
               Microsoft.Office.Core.MsoButtonStyle. _
               msoButtonIconAndCaption
            menuItem.PasteFace()
        
End If
         Return menuItem
      
Catch e As System.Exception
         StructuredErrorHandler(e.ToString)
        
Return menuItem
      
End Try
   End Function

In the OnDisconnection method of the Connect Class, you will need to place the following code to clean up the menus as the add-in shuts down.
  
' delete all menu items and popupmenu
mnuBlockComment.Delete()
mnuBlockAddition.Delete()
popCommentMenu.Delete()

Back to Top

Writing Add-Ins for Visual Studio .NET
Writing Add-ins for Visual Studio .NET
by Les Smith
Apress Publishing