| Author: |
Carlos J. Quintero (Microsoft MVP) |
Applies to: |
Microsoft Visual Studio 2008 |
| Date: |
March 2012 |
|
Microsoft Visual Studio 2010 |
| Updated: |
March 2013 |
|
Microsoft Visual Studio 2012 |
| |
|
|
|
Introduction
This article explains how to create a command with a custom picture in a XML-based add-in
without using a satellite dll, providing the resource file in the own dll of the
add-in. XML-based add-ins were introduced by Visual Studio 2005, use an .AddIn
file to be recognized in the Add-In Manager of Visual Studio and allow the use
of a managed (VB.NET / C#) satellite dlls. However, while Visual Studio 2005
does require a satellite dll, Visual Studio 2008 and higher don't.
More information
The following sample shows the code of an add-in that creates a command with a custom picture
and adds a button to the "Standard" commandbar of Visual Studio. The steps are the following:
- Create an add-in using VB.NET/C# with the name "MyAddin".
- Use the following code in the Connect file:
| Language: VB.NET | Copy Code (IE only) |
Imports System
Imports Microsoft.VisualStudio.CommandBars
Imports Extensibility
Imports EnvDTE
Imports EnvDTE80
Public Class Connect
Implements Extensibility.IDTExtensibility2
Implements IDTCommandTarget
Private Const MY_COMMAND_NAME As String = "MyCommand"
Private Const MY_COMMAND_CAPTION As String = "My command"
Private Const MY_COMMAND_TOOLTIP As String = "My command tooltip"
Private applicationObject As EnvDTE.DTE
Private addInInstance As EnvDTE.AddIn
Private myStandardCommandBarButton As CommandBarButton
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
AddTemporaryUI()
End Select
Catch ex As System.Exception
System.Windows.Forms.MessageBox.Show(ex.ToString)
End Try
End Sub
Public Sub OnStartupComplete(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnStartupComplete
AddTemporaryUI()
End Sub
Public Sub AddTemporaryUI()
Const VS_STANDARD_COMMANDBAR_NAME As String = "Standard"
Const MY_IMAGE_ID As Integer = 101
Dim myCommand As Command = Nothing
Dim standardCommandBar As CommandBar
Dim commandBars As CommandBars
Try
' Try to get the command if already exists
Try
myCommand = applicationObject.Commands.Item(addInInstance.ProgID & "." & MY_COMMAND_NAME)
Catch
End Try
' Add the command if it does not exist
If myCommand Is Nothing Then
myCommand = applicationObject.Commands.AddNamedCommand(addInInstance, MY_COMMAND_NAME, _
MY_COMMAND_CAPTION, MY_COMMAND_TOOLTIP, False, MY_IMAGE_ID, Nothing, _
vsCommandStatus.vsCommandStatusSupported Or vsCommandStatus.vsCommandStatusEnabled)
End If
' Get the "Standard" commmandbar
commandBars = DirectCast(applicationObject.CommandBars, CommandBars)
standardCommandBar = commandBars.Item(VS_STANDARD_COMMANDBAR_NAME)
' Add a button to the commandbar
myStandardCommandBarButton = DirectCast(myCommand.AddControl(standardCommandBar, _
standardCommandBar.Controls.Count + 1), CommandBarButton)
' Set the properties of the button
myStandardCommandBarButton.Caption = MY_COMMAND_CAPTION
myStandardCommandBarButton.Style = MsoButtonStyle.msoButtonIcon
myStandardCommandBarButton.BeginGroup = True
Catch ex As System.Exception
System.Windows.Forms.MessageBox.Show(ex.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 (myStandardCommandBarButton Is Nothing) Then
myStandardCommandBarButton.Delete()
End If
End Select
Catch ex As System.Exception
System.Windows.Forms.MessageBox.Show(ex.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
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
handled = False
If (executeOption = vsCommandExecOption.vsCommandExecOptionDoDefault) Then
If cmdName = addInInstance.ProgID & "." & MY_COMMAND_NAME Then
handled = True
System.Windows.Forms.MessageBox.Show("Command executed.")
End If
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
If neededText = vsCommandStatusTextWanted.vsCommandStatusTextWantedNone Then
If cmdName = addInInstance.ProgID & "." & MY_COMMAND_NAME Then
statusOption = CType(vsCommandStatus.vsCommandStatusEnabled + _
vsCommandStatus.vsCommandStatusSupported, vsCommandStatus)
Else
statusOption = vsCommandStatus.vsCommandStatusUnsupported
End If
End If
End Sub
End Class
| Language: C# | Copy Code (IE only) |
using System;
using Extensibility;
using EnvDTE;
using EnvDTE80;
using Microsoft.VisualStudio.CommandBars;
using System.Resources;
using System.Reflection;
using System.Globalization;
using System.Windows.Forms;
namespace MyAddin
{
public class Connect : Extensibility.IDTExtensibility2, IDTCommandTarget
{
private const string MY_COMMAND_NAME = "MyCommand";
private const string MY_COMMAND_CAPTION = "My command";
private const string MY_COMMAND_TOOLTIP = "My command tooltip";
private EnvDTE.DTE applicationObject;
private EnvDTE.AddIn addInInstance;
private CommandBarButton myStandardCommandBarButton;
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
AddTemporaryUI();
break;
}
}
catch (System.Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString());
}
}
public void OnStartupComplete(ref System.Array custom)
{
AddTemporaryUI();
}
public void AddTemporaryUI()
{
const string VS_STANDARD_COMMANDBAR_NAME = "Standard";
const int MY_IMAGE_ID = 101;
Command myCommand = null;
CommandBar standardCommandBar = null;
CommandBars commandBars = null;
object[] contextUIGuids = new object[] { };
try
{
// Try to get the command if already exists
try
{
myCommand = applicationObject.Commands.Item(addInInstance.ProgID + "." + MY_COMMAND_NAME, -1);
}
catch
{
}
// Add the command if it does not exist
if (myCommand == null)
{
myCommand = applicationObject.Commands.AddNamedCommand(addInInstance,
MY_COMMAND_NAME, MY_COMMAND_CAPTION, MY_COMMAND_TOOLTIP, false, MY_IMAGE_ID, ref contextUIGuids,
(int)(vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled));
}
// Get the "Standard" commandbar
commandBars = (CommandBars)applicationObject.CommandBars;
standardCommandBar = commandBars[VS_STANDARD_COMMANDBAR_NAME];
// Add a button to the commandbar
myStandardCommandBarButton = (CommandBarButton)myCommand.AddControl(standardCommandBar,
standardCommandBar.Controls.Count + 1);
// Set the properties of the button
myStandardCommandBarButton.Caption = MY_COMMAND_CAPTION;
myStandardCommandBarButton.Style = MsoButtonStyle.msoButtonIcon;
myStandardCommandBarButton.BeginGroup = true;
}
catch (System.Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.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 ((myStandardCommandBarButton != null))
{
myStandardCommandBarButton.Delete(true);
}
break;
}
}
catch (System.Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString());
}
}
public void OnBeginShutdown(ref System.Array custom)
{
}
public void OnAddInsUpdate(ref System.Array custom)
{
}
public void Exec(string cmdName, vsCommandExecOption executeOption, ref object varIn,
ref object varOut, ref bool handled)
{
handled = false;
if ((executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault))
{
if (cmdName == addInInstance.ProgID + "." + MY_COMMAND_NAME)
{
handled = true;
System.Windows.Forms.MessageBox.Show("Command executed.");
}
}
}
public void QueryStatus(string cmdName, vsCommandStatusTextWanted neededText,
ref vsCommandStatus statusOption, ref object commandText)
{
if (neededText == vsCommandStatusTextWanted.vsCommandStatusTextWantedNone)
{
if (cmdName == addInInstance.ProgID + "." + MY_COMMAND_NAME)
{
statusOption = (vsCommandStatus)(vsCommandStatus.vsCommandStatusEnabled |
vsCommandStatus.vsCommandStatusSupported);
}
else
{
statusOption = vsCommandStatus.vsCommandStatusUnsupported;
}
}
}
}
}
- Add a new Resource File to the project named "Resource1.resx".
- In the Resource1.resx document window, click the "Add Resource", "New Image", "BMP Image..." button.
- Enter a name for the image, for example "MyImage".
- Make active the image and in the Properties window:
- Change the dimensions of the bitmap setting the Height and Width properties to 16.
- Change the Colors property to 24 bit.
- Draw or paste an image for your bitmap.
- To use transparency you need to use a special color:
- Select a color that you don't use in the Colors window.
- Click the "Image", "Adjust Colors…" menu.
- Enter the values Red=0, Green=254 (not 255!) and Blue=0 (almost pure green). You
can use now this color to fill the transparent areas.
- Select the Resource1.resx file in the Solution Explorer and open it.
- Select the image and in the Properties window change the "(Name)" property from
"MyImage" to 101, which is the value of the MY_IMAGE_ID constant used when
calling the AddNamedCommand method in the code of the add-in.
- To remove the "The resource name 'n' is not a valid identifier" warning
that appears in the
Error List window when using a number as name for the "(Name)" property of the
previous step, select the Resources.resx file in the Solution Explorer
window, and in the Properties window:
- Clear the "Custom Tool " property.
- Clear the "Custom Tool Namespace" property.
- Save all changes.
- Close the windows.
- Rebuild the
solution.
- Run the solution, which will open a second Visual Studio instance.
- Load the add-in.
Related articles
Go back to the 'Resources for Visual Studio .NET extensibility' section for more articles like this
|