| Author: |
Carlos J. Quintero (Microsoft MVP) |
Applies to: |
Microsoft Visual Studio .NET 2002 |
| Date: |
August 2011 |
|
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
This article shows how to create and display a context menu with the same look
and feel than the ones of Visual Studio to be used in your own add-in
user-interface.
More Information
The following add-in creates two commands and shows a modal window when loaded
that, when right-clicked, shows a context menu using a commandBar popup of
Visual Studio. This is done creating a CommandBar of the type popup and calling
its ShowPopup method:
Code for the Connect class:
| Language: C# | Copy Code (IE only) |
using System;
using Microsoft.VisualStudio.CommandBars;
using Extensibility;
using EnvDTE;
using EnvDTE80;
using System.Windows.Forms;
namespace MyAddin
{
public class Connect : Extensibility.IDTExtensibility2, IDTCommandTarget, IWin32Window
{
// Constants for command properties
private const string MY_COMMAND_NAME1 = "MyCommand1";
private const string MY_COMMAND_NAME2 = "MyCommand2";
private const string MY_COMMAND_CAPTION1 = "My command 1";
private const string MY_COMMAND_CAPTION2 = "My command 2";
private const string MY_COMMAND_TOOLTIP1 = "My command tooltip 1";
private const string MY_COMMAND_TOOLTIP2 = "My command tooltip 2";
// Variables for IDE and add-in instances
private EnvDTE.DTE applicationObject;
private EnvDTE.AddIn addInInstance;
// CommandBar that will be created by the add-in
// We must keep it at class level to remove it when the add-in is unloaded
private CommandBar myTemporaryCommandBar;
public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode,
object addInInst, ref System.Array custom)
{
try
{
applicationObject = (EnvDTE.DTE)application;
addInInstance = (EnvDTE.AddIn)addInInst;
switch (connectMode)
{
case ext_ConnectMode.ext_cm_UISetup:
// Do nothing for this add-in with temporary user interface
break;
case ext_ConnectMode.ext_cm_Startup:
// The add-in was marked to load on startup
// Do nothing at this point because the IDE may not be fully initialized
// Visual Studio will call OnStartupComplete when fully initialized
break;
case ext_ConnectMode.ext_cm_AfterStartup:
// The add-in was loaded by hand after startup using the Add-In Manager
// Initialize it in the same way that when is loaded on startup
InitializeAddIn();
break;
}
}
catch (System.Exception e)
{
System.Windows.Forms.MessageBox.Show(e.ToString());
}
}
public void OnStartupComplete(ref System.Array custom)
{
AddTemporaryUI();
}
private EnvDTE.Command CreateCommand(string commandName, string commandCaption, string commandTooltip)
{
EnvDTE.Command command = null;
// Try to retrieve the command, just in case it was already created, ignoring the
// exception that would happen if the command was not created yet.
try
{
command = applicationObject.Commands.Item(addInInstance.ProgID + "." + commandName);
}
catch
{
}
// Add the command if it does not exist
if (command == null)
{
command = applicationObject.Commands.AddNamedCommand(addInInstance, commandName, commandCaption, commandTooltip, true,
59, null, (int)(vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled));
}
return command;
}
private void InitializeAddIn()
{
// Constant for the name of the commandbar created by the add-in
const string MY_TEMPORARY_COMMANDBAR_POPUP_NAME = "MyTemporaryCommandBarPopup";
// The commands that will be created
Command myCommand1 = null;
Command myCommand2 = null;
Form1 myForm1;
// Buttons that will be created on the commandbar popup created by the add-in
// We don't need to keep them at class level to remove them when the add-in is unloaded
// because we will remove the whole commandbar popup
CommandBarButton myCommandBarPopupButton1;
CommandBarButton myCommandBarPopupButton2;
// The collection of Visual Studio commandbars
CommandBars commandBars;
try
{
// Create the commmands
myCommand1 = CreateCommand(MY_COMMAND_NAME1, MY_COMMAND_CAPTION1, MY_COMMAND_TOOLTIP1);
myCommand2 = CreateCommand(MY_COMMAND_NAME2, MY_COMMAND_CAPTION2, MY_COMMAND_TOOLTIP2);
// Retrieve the collection of commandbars
// Note:
// - In VS.NET 2002/2003 (which uses the Office.dll reference) DTE.CommandBars returns directly a CommandBars type, so a cast
// to CommandBars is redundant
// - In VS 2005 or higher (which uses the new Microsoft.VisualStudio.CommandBars.dll reference)
// DTE.CommandBars returns an Object type, so we do need a cast to CommandBars
commandBars = (CommandBars)applicationObject.CommandBars;
// Add a new popup commandbar
myTemporaryCommandBar = commandBars.Add(MY_TEMPORARY_COMMANDBAR_POPUP_NAME, MsoBarPosition.msoBarPopup, null, true);
// Add new buttons on that commandbar popup
myCommandBarPopupButton1 = (CommandBarButton)myCommand1.AddControl(myTemporaryCommandBar, 1);
myCommandBarPopupButton2 = (CommandBarButton)myCommand2.AddControl(myTemporaryCommandBar, 2);
myForm1 = new Form1();
using (myForm1)
{
myForm1.ShowDialog(this, myTemporaryCommandBar);
}
}
catch (System.Exception e)
{
System.Windows.Forms.MessageBox.Show(e.ToString());
}
}
public void OnDisconnection(Extensibility.ext_DisconnectMode RemoveMode, ref System.Array custom)
{
try
{
switch (RemoveMode)
{
case ext_DisconnectMode.ext_dm_HostShutdown:
case ext_DisconnectMode.ext_dm_UserClosed:
if ((myTemporaryCommandBar != null))
{
myTemporaryCommandBar.Delete();
}
break;
}
}
catch (System.Exception e)
{
System.Windows.Forms.MessageBox.Show(e.ToString());
}
}
public void OnBeginShutdown(ref System.Array custom)
{
}
public void OnAddInsUpdate(ref System.Array custom)
{
}
private string GetCommandShortName(string cmdFullName)
{
string cmdShortName;
// Remove the ProgId part from the full name
cmdShortName = cmdFullName.Substring(cmdFullName.LastIndexOf(".") + 1);
return cmdShortName;
}
public void Exec(string cmdName, vsCommandExecOption executeOption, ref object varIn,
ref object varOut, ref bool handled)
{
string cmdShortName;
handled = false;
if ((executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault))
{
cmdShortName = GetCommandShortName(cmdName);
switch (cmdShortName)
{
case MY_COMMAND_NAME1:
handled = true;
MessageBox.Show("Command1 executed.");
break;
case MY_COMMAND_NAME2:
handled = true;
MessageBox.Show("Command2 executed.");
break;
}
}
}
public void QueryStatus(string cmdName, vsCommandStatusTextWanted neededText,
ref vsCommandStatus statusOption, ref object commandText)
{
string cmdShortName;
if (neededText == vsCommandStatusTextWanted.vsCommandStatusTextWantedNone)
{
cmdShortName = GetCommandShortName(cmdName);
switch (cmdShortName)
{
case MY_COMMAND_NAME1:
statusOption = (vsCommandStatus)(vsCommandStatus.vsCommandStatusEnabled | vsCommandStatus.vsCommandStatusSupported);
break;
case MY_COMMAND_NAME2:
statusOption = (vsCommandStatus)(vsCommandStatus.vsCommandStatusEnabled | vsCommandStatus.vsCommandStatusSupported);
break;
default:
statusOption = vsCommandStatus.vsCommandStatusUnsupported;
break;
}
}
}
public System.IntPtr Handle
{
get
{
// Wraps the Win32 handle of the Visual Studio main window
return new System.IntPtr(applicationObject.MainWindow.HWnd);
}
}
}
}
Code for the Form1 class:
| Language: C# | Copy Code (IE only) |
using Microsoft.VisualStudio.CommandBars;
using System.Windows.Forms;
namespace MyAddin
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
CommandBar myContextMenu;
public DialogResult ShowDialog(IWin32Window parent, CommandBar myCommandBar)
{
this.Text = "Right-click on me";
this.StartPosition = FormStartPosition.CenterScreen;
this.ShowInTaskbar = false;
myContextMenu = myCommandBar;
return base.ShowDialog(parent);
}
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
System.Drawing.Point point;
if (e.Button == MouseButtons.Right)
{
try
{
// The ShowPopup method requires screen coordinates
point = this.PointToScreen(new System.Drawing.Point(e.X, e.Y));
myContextMenu.ShowPopup(point.X, point.Y);
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}
}
Code for the Connect class:
| Language: VB.NET | Copy Code (IE only) |
Imports System
Imports Microsoft.VisualStudio.CommandBars
Imports Extensibility
Imports EnvDTE
Imports EnvDTE80
Imports System.Windows.Forms
Public Class Connect
Implements Extensibility.IDTExtensibility2
Implements IDTCommandTarget
Implements IWin32Window
' Constants for command properties
Private Const MY_COMMAND_NAME1 As String = "MyCommand1"
Private Const MY_COMMAND_NAME2 As String = "MyCommand2"
Private Const MY_COMMAND_CAPTION1 As String = "My command 1"
Private Const MY_COMMAND_CAPTION2 As String = "My command 2"
Private Const MY_COMMAND_TOOLTIP1 As String = "My command tooltip 1"
Private Const MY_COMMAND_TOOLTIP2 As String = "My command tooltip 2"
' Variables for IDE and add-in instances
Private applicationObject As EnvDTE.DTE
Private addInInstance As EnvDTE.AddIn
' CommandBar that will be created by the add-in
' We must keep it at class level to remove it when the add-in is unloaded
Private myTemporaryCommandBar As CommandBar
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
applicationObject = CType(application, EnvDTE.DTE)
addInInstance = CType(addInInst, EnvDTE.AddIn)
Select Case connectMode
Case ext_ConnectMode.ext_cm_UISetup
' Do nothing for this add-in with temporary user interface
Case ext_ConnectMode.ext_cm_Startup
' The add-in was marked to load on startup
' Do nothing at this point because the IDE may not be fully initialized
' Visual Studio will call OnStartupComplete when fully initialized
Case ext_ConnectMode.ext_cm_AfterStartup
' The add-in was loaded by hand after startup using the Add-In Manager
' Initialize it in the same way that when is loaded on startup
InitializeAddIn()
End Select
Catch e As System.Exception
System.Windows.Forms.MessageBox.Show(e.ToString)
End Try
End Sub
Public Sub OnStartupComplete(ByRef custom As System.Array) _
Implements Extensibility.IDTExtensibility2.OnStartupComplete
InitializeAddIn()
End Sub
Private Function CreateCommand(ByVal commandName As String, ByVal commandCaption As String, ByVal commandTooltip As String) As EnvDTE.Command
Dim command As EnvDTE.Command = Nothing
' Try to retrieve the command, just in case it was already created, ignoring the
' exception that would happen if the command was not created yet.
Try
command = applicationObject.Commands.Item(addInInstance.ProgID & "." & commandName)
Catch
End Try
' Add the command if it does not exist
If command Is Nothing Then
command = applicationObject.Commands.AddNamedCommand(addInInstance, commandName, commandCaption, commandTooltip, True, _
59, Nothing, vsCommandStatus.vsCommandStatusSupported Or vsCommandStatus.vsCommandStatusEnabled)
End If
Return command
End Function
Private Sub InitializeAddIn()
' Constant for the name of the commandbar created by the add-in
Const MY_TEMPORARY_COMMANDBAR_POPUP_NAME As String = "MyTemporaryCommandBarPopup"
' The commands that will be created
Dim myCommand1 As Command = Nothing
Dim myCommand2 As Command = Nothing
Dim myForm1 As Form1
' Buttons that will be created on the commandbar popup created by the add-in
' We don't need to keep them at class level to remove them when the add-in is unloaded
' because we will remove the whole commandbar popup
Dim myCommandBarPopupButton1 As CommandBarButton
Dim myCommandBarPopupButton2 As CommandBarButton
' The collection of Visual Studio commandbars
Dim commandBars As CommandBars
Try
' Create the commmands
myCommand1 = CreateCommand(MY_COMMAND_NAME1, MY_COMMAND_CAPTION1, MY_COMMAND_TOOLTIP1)
myCommand2 = CreateCommand(MY_COMMAND_NAME2, MY_COMMAND_CAPTION2, MY_COMMAND_TOOLTIP2)
' Retrieve the collection of commandbars
' Note:
' - In VS.NET 2002/2003 (which uses the Office.dll reference) DTE.CommandBars returns directly a CommandBars type, so a cast
' to CommandBars is redundant
' - In VS 2005 or higher (which uses the new Microsoft.VisualStudio.CommandBars.dll reference)
' DTE.CommandBars returns an Object type, so we do need a cast to CommandBars
commandBars = DirectCast(applicationObject.CommandBars, CommandBars)
' Add a new popup commandbar
myTemporaryCommandBar = commandBars.Add(MY_TEMPORARY_COMMANDBAR_POPUP_NAME, MsoBarPosition.msoBarPopup, Nothing, True)
' Add new buttons on that commandbar popup
myCommandBarPopupButton1 = DirectCast(myCommand1.AddControl(myTemporaryCommandBar, 1), CommandBarButton)
myCommandBarPopupButton2 = DirectCast(myCommand2.AddControl(myTemporaryCommandBar, 2), CommandBarButton)
myForm1 = New Form1()
Using (myForm1)
myForm1.ShowDialog(Me, myTemporaryCommandBar)
End Using
Catch e As System.Exception
System.Windows.Forms.MessageBox.Show(e.ToString)
End Try
End Sub
Public Sub OnDisconnection(ByVal RemoveMode As Extensibility.ext_DisconnectMode, ByRef custom As System.Array) _
Implements Extensibility.IDTExtensibility2.OnDisconnection
Try
Select Case RemoveMode
Case ext_DisconnectMode.ext_dm_HostShutdown, ext_DisconnectMode.ext_dm_UserClosed
If Not (myTemporaryCommandBar Is Nothing) Then
myTemporaryCommandBar.Delete()
End If
End Select
Catch e As System.Exception
System.Windows.Forms.MessageBox.Show(e.ToString)
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
Private Function GetCommandShortName(ByVal cmdFullName As String) As String
Dim cmdShortName As String
' Remove the ProgId part from the full name
cmdShortName = cmdFullName.Substring(cmdFullName.LastIndexOf(".") + 1)
Return cmdShortName
End Function
Public Sub Exec(ByVal cmdName As String, ByVal executeOption As vsCommandExecOption, _
ByRef varIn As Object, ByRef varOut As Object, ByRef handled As Boolean) _
Implements IDTCommandTarget.Exec
Dim cmdShortName As String
handled = False
If (executeOption = vsCommandExecOption.vsCommandExecOptionDoDefault) Then
cmdShortName = GetCommandShortName(cmdName)
Select Case cmdShortName
Case MY_COMMAND_NAME1
handled = True
MessageBox.Show("Command1 executed.")
Case MY_COMMAND_NAME2
handled = True
MessageBox.Show("Command2 executed.")
End Select
End If
End Sub
Public Sub QueryStatus(ByVal cmdName As String, ByVal neededText As vsCommandStatusTextWanted, _
ByRef statusOption As vsCommandStatus, ByRef commandText As Object) _
Implements IDTCommandTarget.QueryStatus
Dim cmdShortName As String
If neededText = vsCommandStatusTextWanted.vsCommandStatusTextWantedNone Then
cmdShortName = GetCommandShortName(cmdName)
Select Case cmdShortName
Case MY_COMMAND_NAME1
statusOption = CType(vsCommandStatus.vsCommandStatusEnabled + vsCommandStatus.vsCommandStatusSupported, vsCommandStatus)
Case MY_COMMAND_NAME2
statusOption = CType(vsCommandStatus.vsCommandStatusEnabled + vsCommandStatus.vsCommandStatusSupported, vsCommandStatus)
Case Else
statusOption = vsCommandStatus.vsCommandStatusUnsupported
End Select
End If
End Sub
Public ReadOnly Property Handle As System.IntPtr Implements System.Windows.Forms.IWin32Window.Handle
Get
' Wraps the Win32 handle of the Visual Studio main window
Return New System.IntPtr(applicationObject.MainWindow.HWnd)
End Get
End Property
End Class
Code for the Form1 class:
| Language: VB.NET | Copy Code (IE only) |
Imports Microsoft.VisualStudio.CommandBars
Imports System.Windows.Forms
Public Class Form1
Private myContextMenu As CommandBar
Public Overloads Function ShowDialog(ByVal parent As IWin32Window, ByVal myCommandBar As CommandBar) As DialogResult
Me.Text = "Right-click on me"
Me.StartPosition = FormStartPosition.CenterScreen
Me.ShowInTaskbar = False
myContextMenu = myCommandBar
Return MyBase.ShowDialog(parent)
End Function
Private Sub Form1_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseClick
Dim point As System.Drawing.Point
If e.Button = Windows.Forms.MouseButtons.Right Then
Try
' The ShowPopup method requires screen coordinates
point = Me.PointToScreen(New System.Drawing.Point(e.X, e.Y))
myContextMenu.ShowPopup(point.X, point.Y)
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
End If
End Sub
End Class
Related articles
Go back to the 'Resources for Visual Studio .NET extensibility' section for more articles like this