Logo
HOWTO: Add a popup command bar to the context menu of a code window of Visual Studio .NET

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio .NET 2002
Date: August 2004   Microsoft Visual Studio .NET 2003
Updated March 2013   Microsoft Visual Studio 2005
      Microsoft Visual Studio 2008
      Microsoft Visual Studio 2010
      Microsoft Visual Studio 2012
Introduction

When creating addins for Visual Studio .NET, sometimes you may want to add some menus in the context menu of a code window of Visual Studio .NET. This article shows the code to do it, using a popup command bar to group all the menus of your addin.

More Information

The following sample of an add-in adds two commands to Visual Studio in the ext_cm_UISetup phase and when the add-in is loaded it creates a popup command bar in the context menu of the code window and adds a submenu for each command:

Language: VB.NET   Copy Code Copy Code (IE only)
Public Class Connect
   Implements Extensibility.IDTExtensibility2, EnvDTE.IDTCommandTarget

   Private Const m_NAME_COMMAND1 As String = "MyCommand1"
   Private Const m_NAME_COMMAND2 As String = "MyCommand2"

   Private m_dte As EnvDTE.DTE
   Private m_addIn As EnvDTE.AddIn

   Private m_commandBarPopup As CommandBarPopup
   Private m_commandBarControl1 As CommandBarControl
   Private m_commandBarControl2 As CommandBarControl

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

      Try

         m_dte = CType(application, EnvDTE.DTE)
         m_addIn = CType(addInInst, EnvDTE.AddIn)

         Select Case connectMode

            Case ext_ConnectMode.ext_cm_UISetup

               ' Create commands in the UI Setup phase. This phase is called only once when the add-in is deployed.
               CreateCommands()

            Case ext_ConnectMode.ext_cm_Startup

               ' Do nothing yet, wait until the IDE is fully initialized (OnStartupComplete will be called)

            Case ext_ConnectMode.ext_cm_AfterStartup

               InitializeAddIn()

         End Select

      Catch objException As Exception
         MessageBox.Show(objException.ToString, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
      End Try

   End Sub

   Public Sub OnStartupComplete(ByRef custom As System.Array) _
      Implements Extensibility.IDTExtensibility2.OnStartupComplete

      InitializeAddIn()

   End Sub

   Private Sub CreateCommands()

      m_dte.Commands.AddNamedCommand(m_addIn, m_NAME_COMMAND1, "MyCommand 1", "MyCommand 1", True, 59)
      m_dte.Commands.AddNamedCommand(m_addIn, m_NAME_COMMAND2, "MyCommand 2", "MyCommand 2", True, 59)

   End Sub

   Private Sub InitializeAddIn()

      Dim myCommandBarControl As CommandBarControl
      Dim codeWindowCommandBar As CommandBar
      Dim myCommand1 As Command
      Dim myCommand2 As Command
      Dim commandBars As CommandBars

      ' Retrieve commands created in the ext_cm_UISetup phase of the OnConnection method
      myCommand1 = m_dte.Commands.Item(m_addIn.ProgID & "." & m_NAME_COMMAND1)
      myCommand2 = m_dte.Commands.Item(m_addIn.ProgID & "." & m_NAME_COMMAND2)

      ' Retrieve the context menu of code windows
      commandBars = CType(m_dte.CommandBars, CommandBars)
      codeWindowCommandBar = commandBars.Item("Code Window")

      ' Add a popup command bar
      myCommandBarControl = codeWindowCommandBar.Controls.Add( _
          MsoControlType.msoControlPopup, System.Type.Missing, _
          System.Type.Missing, System.Type.Missing, System.Type.Missing)

      m_commandBarPopup = DirectCast(myCommandBarControl, CommandBarPopup)

      ' Change its caption
      m_commandBarPopup.Caption = "My popup"

      ' Add controls to the popup command bar
      m_commandBarControl1 = CType(myCommand1.AddControl(m_commandBarPopup.CommandBar), CommandBarControl)
      m_commandBarControl2 = CType(myCommand2.AddControl(m_commandBarPopup.CommandBar), CommandBarControl)

   End Sub

   Public Sub OnDisconnection(ByVal RemoveMode As Extensibility.ext_DisconnectMode, ByRef custom As System.Array) _
      Implements Extensibility.IDTExtensibility2.OnDisconnection

      Try

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

      Catch objException As Exception
         MessageBox.Show(objException.ToString, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
      End Try

   End Sub

   Public Sub OnBeginShutdown(ByRef custom As System.Array) _
      Implements Extensibility.IDTExtensibility2.OnBeginShutdown

   End Sub

   Public Sub OnAddInsUpdate(ByRef custom As System.Array) _
      Implements Extensibility.IDTExtensibility2.OnAddInsUpdate

   End Sub

   Public Sub QueryStatus(ByVal CmdName As String, _
       ByVal NeededText As EnvDTE.vsCommandStatusTextWanted, _
       ByRef StatusOption As EnvDTE.vsCommandStatus, ByRef CommandText As Object) _
       Implements EnvDTE.IDTCommandTarget.QueryStatus

      Select Case CmdName

         Case m_addIn.ProgID & "." & m_NAME_COMMAND1

            StatusOption = vsCommandStatus.vsCommandStatusSupported Or _
                vsCommandStatus.vsCommandStatusEnabled

         Case m_addIn.ProgID & "." & m_NAME_COMMAND2

            StatusOption = vsCommandStatus.vsCommandStatusSupported Or _
                vsCommandStatus.vsCommandStatusEnabled

      End Select

   End Sub

   Public Sub Exec(ByVal CmdName As String, ByVal ExecuteOption As EnvDTE.vsCommandExecOption, _
      ByRef VariantIn As Object, ByRef VariantOut As Object, ByRef handled As Boolean) _
      Implements EnvDTE.IDTCommandTarget.Exec

      Select Case CmdName

         Case m_addIn.ProgID & "." & m_NAME_COMMAND1

            MessageBox.Show("MyCommand1 executed")

         Case m_addIn.ProgID & "." & m_NAME_COMMAND2

            MessageBox.Show("MyCommand2 executed")

      End Select

   End Sub

End Class
Language: C#   Copy Code Copy Code (IE only)
public class Connect: Extensibility.IDTExtensibility2, EnvDTE.IDTCommandTarget
{
   private const string m_NAME_COMMAND1 = "MyCommand1";
   private const string m_NAME_COMMAND2 = "MyCommand2";

   private EnvDTE.DTE m_dte;
   private EnvDTE.AddIn m_addIn;

   private CommandBarPopup m_commandBarPopup;
   private CommandBarControl m_commandBarControl1;
   private CommandBarControl m_commandBarControl2;

   public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, 
      object addInInst, ref System.Array custom)
   {
      try
      {
         m_dte = (EnvDTE.DTE) application;
         m_addIn = (EnvDTE.AddIn) addInInst;

         switch (connectMode)
         {
            case ext_ConnectMode.ext_cm_UISetup:

               // Create commands in the UI Setup phase. This phase is called only once when the add-in is deployed.
               CreateCommands();
               break;

            case ext_ConnectMode.ext_cm_AfterStartup:
               
               InitializeAddIn();
               break;

            case ext_ConnectMode.ext_cm_Startup:
               
               // Do nothing yet, wait until the IDE is fully initialized (OnStartupComplete will be called)
               break;
         }
      }
      catch (Exception ex)
      {
         MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
   }

   public void OnStartupComplete(ref System.Array custom)
   {
      InitializeAddIn();
   }
	
   private void CreateCommands()
   {
      object[] contextUIGuids = new object[] {};

      m_dte.Commands.AddNamedCommand(m_addIn, m_NAME_COMMAND1, "MyCommand 1", "MyCommand 1", true, 59, 
         ref contextUIGuids, (int)vsCommandStatus.vsCommandStatusSupported);
         
      m_dte.Commands.AddNamedCommand(m_addIn, m_NAME_COMMAND2, "MyCommand 2", "MyCommand 2", true, 59, 
         ref contextUIGuids, (int)vsCommandStatus.vsCommandStatusSupported);
   }

   private void InitializeAddIn()
   {
      CommandBarControl myCommandBarControl;
      CommandBar codeWindowCommandBar;
      Command myCommand1;
      Command myCommand2;
      CommandBars commandBars;

      // Retrieve commands created in the ext_cm_UISetup phase of the OnConnection method
      myCommand1 = m_dte.Commands.Item(m_addIn.ProgID + "." + m_NAME_COMMAND1, -1);
      myCommand2 = m_dte.Commands.Item(m_addIn.ProgID + "." + m_NAME_COMMAND2, -1);

      // Retrieve the context menu of code windows
      commandBars = (CommandBars)m_dte.CommandBars;
      codeWindowCommandBar = commandBars["Code Window"];

      // Add a popup command bar
      myCommandBarControl = codeWindowCommandBar.Controls.Add(MsoControlType.msoControlPopup, 
         System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing);

      m_commandBarPopup = (CommandBarPopup)myCommandBarControl;

      // Change its caption
      m_commandBarPopup.Caption = "My popup";

      // Add controls to the popup command bar
      m_commandBarControl1 = (CommandBarControl) myCommand1.AddControl(m_commandBarPopup.CommandBar, 
         m_commandBarPopup.Controls.Count + 1);

      m_commandBarControl2 = (CommandBarControl) myCommand2.AddControl(m_commandBarPopup.CommandBar, 
         m_commandBarPopup.Controls.Count + 1);
   }
	
   public void OnBeginShutdown(ref System.Array custom)
   {
   }

   public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode, ref System.Array custom)
   {
      try
      {
         if (m_commandBarPopup != null)
         {
            m_commandBarPopup.Delete(true);
         }
      }
      catch (Exception ex)
      {
         MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
   }

   public void OnAddInsUpdate(ref System.Array custom)
   {
   }

   public void QueryStatus(string CmdName, vsCommandStatusTextWanted NeededText, 
      ref vsCommandStatus StatusOption, ref object CommandText)
   {
      if (CmdName == m_addIn.ProgID + "." + m_NAME_COMMAND1)
      {
         StatusOption = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
      }
      else if (CmdName == m_addIn.ProgID + "." + m_NAME_COMMAND2)
      {
          StatusOption = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
      }
   }

   public void Exec(string CmdName, vsCommandExecOption ExecuteOption, ref object VariantIn, 
      ref object VariantOut, ref bool Handled)
   {
      if (CmdName == m_addIn.ProgID + "." + m_NAME_COMMAND1)
      {
         MessageBox.Show("MyCommand1 executed");
      }
      else if (CmdName == m_addIn.ProgID + "." + m_NAME_COMMAND2)
      {
         MessageBox.Show("MyCommand2 executed");
      }
   }
}

Related articles


Go back to the 'Resources for Visual Studio .NET extensibility' section for more articles like this


Top