Compartir a través de


Cómo: Mostrar un icono personalizado en un botón de complemento

Actualización: noviembre 2007

Puede reemplazar el icono predeterminado (una cara sonriente) que se muestra junto al comando del complemento por un icono que no sea ninguno de los iconos estándar predefinidos, como se explica en Cómo: Cambiar el icono predeterminado de un complemento.

Para hacer esto:

  • Coloque el mapa de bits del icono como un recurso recurso en un archivo DLL satélite.

  • Establezca el parámetro MSOButton en el método AddNamedCommand2 en false (que indica al método que busque el mapa de bits del icono en el archivo DLL satélite).

  • Haga referencia al número de Id. de ese recurso en la parte de la barra de comandos del proyecto de complemento.

El procedimiento siguiente muestra cómo agregar un icono personalizado al botón de complemento.

Nota:

Los cuadros de diálogo y comandos de menú que se ven pueden diferir de los descritos en la Ayuda, en función de la configuración activa o la edición. Estos procedimientos se han desarrollado con la Configuración de desarrollo general activa. Para cambiar la configuración, elija la opción Importar y Exportarconfiguraciones en el menú Herramientas. Para obtener más información, vea Valores de configuración de Visual Studio.

Para agregar un mapa de bits personalizado como un icono de botón de complemento a un proyecto de complemento

  1. Abra una solución de complemento existente o cree una nueva solución de complemento en Visual Studio.

    Si crea un nuevo complemento, no olvide activar la opción "¿Desea crear la interfaz de usuario de barra de comandos para el complemento?"

  2. Agregue un nuevo archivo de recursos al proyecto de complemento. Para hacerlo:

    1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en el proyecto de complemento.

    2. Seleccione Nuevo elemento en el menú Agregar.

    3. Seleccione Archivo de recursos en la lista Plantillas y haga clic en el botón Agregar. Deje su nombre predeterminado (Resources1.resx).

      Esto inicia el Editor de recursos de Visual Studio.

  3. Haga clic en el botón Mostrar todos los archivos en la barra de herramientas del Explorador de soluciones.

  4. En las propiedades para Resource1.resx, establezca la propiedad Acción de generación en Ninguna.

    Los complementos requieren un valor entero como argumento de mapa de bits. Cuando se establece esta propiedad es posible editar el archivo de recursos y nombrar su recurso de mapa de bits con un identificador numérico, algo que no puede hacerse cuando el archivo .resx es parte del proyecto de complemento.

  5. En el Editor de recursos, haga clic en Agregar recurso y, a continuación, seleccione Imagen BMP en el menú Nueva imagen. Por ahora, deje el nombre predeterminado (Image1.bmp).

    Alternativamente, puede seleccionar una imagen de mapa de bits existente que es de 16 x 16 píxeles y 16 colores o Color verdadero. Los iconos personalizados para los complementos deben ser de 16 x 16 píxeles y 16 colores o Color verdadero.

  6. En la ventana de propiedades del mapa de bits, cambie las propiedades Alto y Ancho a 16. Establezca la propiedad Colores en 16 Colores o Color verdadero.

  7. Si creó un nuevo mapa de bits, edite la imagen en el Editor de recursos.

  8. Haga clic con el botón secundario del mouse en el archivo Resource1.resx en el Explorador de soluciones y seleccione Excluir del proyecto.

    Al hacer esto, se evitan errores del compilador innecesarios. No es necesario que el archivo esté en el proyecto. Esto permite utilizar el Editor de recursos integrado.

  9. Abra la clase Connect del complemento. En el método OnConnection de la línea AddNamedCommand2, cambie el valor del parámetro MSOButton de true a false y el valor del parámetro Bitmap de 59 a 1. Por ejemplo:

    command = commands.AddNamedCommand2(_addInInstance, "MyAddin1", " 
    MyAddin1", "Executes the command for MyAddin1", False, 1, Nothing, 
    CType(vsCommandStatus.vsCommandStatusSupported, Integer) + 
    CType(vsCommandStatus.vsCommandStatusEnabled, Integer), 
    vsCommandStyle.vsCommandStylePictAndText, 
    vsCommandControlType.vsCommandControlTypeButton)
    
    Command command = commands.AddNamedCommand2(_addInInstance, 
    "MyAddin1", "MyAddin1", "Executes the command for MyAddin1", false, 
    1, ref contextGUIDS, 
    (int)vsCommandStatus.vsCommandStatusSupported+(int)vsCommandStatus.
    vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, 
    vsCommandControlType.vsCommandControlTypeButton);
    

    Al establecer el argumento MSOButton en falso se fuerza al complemento a buscar su mapa de bits del botón en un archivo de recursos. El número, 1, será el identificador para ese mapa de bits. (Se establece en un paso posterior.)

  10. Cuando termine, seleccione Guardar todo en el menú Archivo, seleccione Generar solución en el menú Generar y, a continuación, cierre la solución.

  11. En el Explorador de Windows, utilice el Bloc de notas para editar el archivo Resource1.resx.

  12. Busque todas las instancias de "Image1" y cámbielas a "1". Cuando termine, guarde el archivo.

  13. En la carpeta \Resources para el complemento, cambie el nombre del archivo de mapa de bits de Image1.bmp a 1.bmp.

  14. Utilice ResGen y Assembly Linker (AL) para generar el archivo DLL satélite. Para hacerlo:

    1. En el menú Inicio, elija Todos los programas, Microsoft Visual Studio 2005, Visual Studio Tools y, por último, haga clic en Símbolo del sistema de Visual Studio.

      Esto establece ciertas variables de entorno para que pueda hacer referencia más fácilmente a las herramientas Visual Studio.

    2. En el símbolo del sistema, vaya a la carpeta que contiene el archivo .resx y escriba Resgen Resource1.resx.

      Resgen es una utilidad que compila el archivo .resx especificado en un archivo .resources. Para obtener más información, vea Generador de archivos de recursos (Resgen.exe).

    3. En el símbolo del sistema, escriba lo siguiente: Al.exe /embed:Resource1.resources /culture:en-US /out:<Add-In Name>.resources.dll.

      Reemplace <Add-In Name> por el nombre del complemento. Por ejemplo, si el proyecto de complemento se llama MyAddin1, el modificador /out: sería /out:MyAddin1.resources.dll. Si el nombre de /out: no coincide con el nombre el proyecto, el archivo DLL de recursos no se encontrará.

      Assembly Linker (Al.exe) convierte el archivo .resources especificado en un archivo DLL de recursos satélite al que puede hacer referencia en el complemento (puede cambiar el modificador /culture a un idioma diferente del inglés). Para obtener más información, vea Herramienta Assembly Linker (Al.exe).

  15. Usando el Explorador de Windows, examine el directorio de archivos DLL del complemento (habitualmente la carpeta \bin) t cree una carpeta denominada en-US (para Inglés de EE.UU., porque escribió en-US como valor de referencia cultural en Al).

  16. Copie el archivo <Nombre de complemento>.resources.dll en la nueva carpeta en-US.

  17. En Visual Studio, abra de nuevo el proyecto de complemento y ejecútelo.

  18. Haga clic en el menú Herramientas.

    El complemento aparece en el menú Herramientas junto con el icono personalizado.

Para agregar un mapa de bits personalizado como un icono de botón de complemento a un complemento nativo Visual C++

  1. Siga los mismos procedimientos antes indicados, pero cambie los elementos siguientes.

  2. Cree un nuevo proyecto de DLL Win32 de Visual C++.

  3. Agregue un archivo de recursos (.rc).

  4. En Vista de recursos, agregue un mapa de bits (16 x 16) y dele un Id. numérico.

    El mapa de bits debe tener 16 x 16 píxeles y 16 Colores o Color verdadero.

  5. Actualice el método AddNamedCommand2 en Connect.cpp con MSOButton establecido en VARIANT_FALSE y Bitmap establecido en el Id. del mapa de bits previamente asignado.

  6. Genere el archivo DLL.

  7. Cree una subcarpeta "1033" (para la configuración regional inglesa) en el directorio de archivo DLL de complemento nativo.

  8. Copie el archivo DLL satélite en el directorio "1033".

  9. Abra AddIn.rgs y agregue dos valores de clave de registro "SatelliteDllName" y "SatelliteDllPath". Por ejemplo:

    HKCU
    {
       NoRemove 'SOFTWARE'
       {
          NoRemove 'Microsoft'
          {
             NoRemove 'VisualStudio'
             {
                NoRemove '8.0'
                {
                   NoRemove 'AddIns'
                   {
                      ForceRemove 
                        'NativeAddinCustBitmap.Connect'
                         {
                           val LoadBehavior = d 0
                           val CommandLineSafe = d 0
                           val CommandPreload = d 1
                           val FriendlyName = s 'NativeAddinCustBitmap'
                           val Description = s 'NativeAddinCustBitmap 
                             Description'
                           val SatelliteDllName = s  
                             'NativeAddinCustBitmapUI.dll'
                           val SatelliteDllPath = s 
                             'C:\Test\CustomBitmap\NativeAddinCustBitmap
                             \NativeAddinCustBitmap\Debug'
                         }
                      }
                   }
                }
             }
          }
       }
    

    En "SatelliteDllPath" no agregue el Id. de configuración local en la ruta de acceso. Se anexará automáticamente en tiempo de ejecución.

  10. Vuelva a generar el complemento para registrar la información actualizada.

Ejemplo

A continuación hay un ejemplo de código de complemento completo para un complemento de Visual Basic/Visual C#/Visual J# que hace referencia a un icono personalizado contenido en un archivo DLL de recursos de satélite.

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

Public Class Connect

    Implements IDTExtensibility2
Implements IDTCommandTarget

    Dim _applicationObject As DTE2
    Dim _addInInstance As AddIn

    Public Sub New()

    End Sub

    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)
        If connectMode = ext_ConnectMode.ext_cm_UISetup Then

            Dim commands As Commands2 = CType(_applicationObject. _
              Commands, Commands2)
            Dim toolsMenuName As String
            Try

                ' To move the command to a different 
                ' menu, change the word, Tools, to the English version 
                ' of the menu. This code will take the culture, append 
                ' the name of the menu, and then add the command to 
                ' that menu. A list of all the top-level menus is 
                ' in the file, CommandBar.resx.
                Dim resourceManager As System.Resources. _
                  ResourceManager = New System.Resources. _
                  ResourceManager("MyAddin3.CommandBar", _
                  System.Reflection.Assembly.GetExecutingAssembly())

                Dim cultureInfo As System.Globalization.CultureInfo _
                  = New System.Globalization. _
                  CultureInfo(_applicationObject.LocaleID)
                toolsMenuName = resourceManager.GetString(String. _
                  Concat (cultureInfo.TwoLetterISOLanguageName, _
                  "Tools"))

            Catch e As Exception
                ' We tried to find a localized version of the word, 
                ' Tools, but one was not found. Default to the en-US 
                ' word, which may work for the current culture.
                toolsMenuName = "Tools"
            End Try

            ' Place the command on the Tools menu.
            ' Find the MenuBar command bar, which is the top-level 
            ' command bar holding all the main menu items:
            Dim commandBars As CommandBars = _
              CType(_applicationObject.CommandBars, _
              CommandBars)
            Dim menuBarCommandBar As CommandBar = _
              commandBars.Item("MenuBar")

            ' Find the Tools command bar on the MenuBar command bar.
            Dim toolsControl As CommandBarControl = _
              menuBarCommandBar.Controls.Item(toolsMenuName)
            Dim toolsPopup As CommandBarPopup = CType(toolsControl, _
              CommandBarPopup)

            Try
                ' Add a command to the Commands collection.
                Dim command As Command = _
                  commands.AddNamedCommand2(_addInInstance, _
                  "MyAddin3", "MyAddin3", "Executes the command for _
                  MyAddin3", False, 1, Nothing, _
                  CType(vsCommandStatus.vsCommandStatusSupported, _
                  Integer) + CType(vsCommandStatus. _
                  vsCommandStatusEnabled, Integer), _
                  vsCommandStyle.vsCommandStylePictAndText, _
                  vsCommandControlType.vsCommandControlTypeButton)

                ' Find the appropriate command bar on the MenuBar 
                ' command bar.
                command.AddControl(toolsPopup.CommandBar, 1)
            Catch argumentException As System.ArgumentException
                ' If we are here, then the exception is probably 
                ' because a command with that name already exists. If 
                ' so there is no need to recreate 
                ' the command and we can safely ignore the exception.
            End Try
        End If
    End Sub

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

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

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

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

    Public Sub QueryStatus(ByVal commandName As String, ByVal _
      neededText As vsCommandStatusTextWanted, ByRef status As _
      vsCommandStatus, ByRef commandText As Object) Implements _
      IDTCommandTarget.QueryStatus
        If neededText = vsCommandStatusTextWanted. _
          vsCommandStatusTextWantedNone Then
            If commandName = "MyAddin3.Connect.MyAddin3" Then
                status = CType(vsCommandStatus.vsCommandStatusEnabled _
                  + vsCommandStatus.vsCommandStatusSupported, _
                  vsCommandStatus)
            Else
                status = vsCommandStatus.vsCommandStatusUnsupported
            End If
        End If
    End Sub

    Public Sub Exec(ByVal commandName 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 commandName = "MyAddin3.Connect.MyAddin3" Then
                handled = True
                MsgBox("Add-in is running.")
                Exit Sub
            End If
        End If
    End Sub
End Class
using System;
using Extensibility;
using EnvDTE;
using EnvDTE80;
using Microsoft.VisualStudio.CommandBars;
using System.Resources;
using System.Reflection;
using System.Globalization;

namespace MyAddin1
{
    public class Connect : Object, IDTExtensibility2, IDTCommandTarget
    {
        public Connect()
        {
        }

    public void OnConnection(object application, ext_ConnectMode 
    connectMode, object addInInst, ref Array custom)
    {
        _applicationObject = (DTE2)application;
        _addInInstance = (AddIn)addInInst;
        if(connectMode == ext_ConnectMode.ext_cm_UISetup)
        {
            object []contextGUIDS = new object[] { };
            Commands2 commands = 
             (Commands2)_applicationObject.Commands;
            string toolsMenuName;

            try
            {
                ResourceManager resourceManager = new 
                ResourceManager("MyAddin1.CommandBar", 
                Assembly.GetExecutingAssembly());
                CultureInfo cultureInfo = new 
                  System.Globalization.CultureInfo
                  (_applicationObject.LocaleID);
                string resourceName =  String.Concat(cultureInfo.
                TwoLetterISOLanguageName, "Tools");
                toolsMenuName = 
                resourceManager.GetString(resourceName);
            }
            catch
            {
                toolsMenuName = "Tools";
            }

            CommandBar menuBarCommandBar = 
            ((CommandBars)_applicationObject.CommandBars)["MenuBar"];

            CommandBarControl toolsControl = 
            menuBarCommandBar.Controls[toolsMenuName];
            CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;

            try
            {
                Command command = 
                  commands.AddNamedCommand2(_addInInstance, "MyAddin1", 
                  "MyAddin1", "Executes the command for MyAddin1", 
                  false, 1, ref contextGUIDS, 
                  (int)vsCommandStatus.vsCommandStatusSupported+(int)
                  vsCommandStatus.vsCommandStatusEnabled,  
                  (int)vsCommandStyle.vsCommandStylePictAndText, 
                  vsCommandControlType.vsCommandControlTypeButton);

                if((command != null) && (toolsPopup != null))
                {
                    command.AddControl(toolsPopup.CommandBar, 1);
                }
            }
            catch
            {
            }
        }
    }

    public void OnDisconnection(ext_DisconnectMode disconnectMode, ref 
      Array custom)
    {
    }

    public void OnAddInsUpdate(ref Array custom)
    {
    }

    public void OnStartupComplete(ref Array custom)
    {
    }

    public void OnBeginShutdown(ref Array custom)
    {
    }
            
    public void QueryStatus(string commandName, 
      vsCommandStatusTextWanted neededText, ref vsCommandStatus status, 
      ref object commandText)
    {
        if(neededText == 
        vsCommandStatusTextWanted.vsCommandStatusTextWantedNone)
        {
            if(commandName == "MyAddin1.Connect.MyAddin1")
            {
                status = 
                (vsCommandStatus)vsCommandStatus.
                vsCommandStatusSupported|vsCommandStatus.
                vsCommandStatusEnabled;
            return;
            }
        }
    }

    public void Exec(string commandName, vsCommandExecOption 
    executeOption, ref object varIn, ref object varOut, ref bool 
    handled)
    {
        handled = false;
        if(executeOption == 
          vsCommandExecOption.vsCommandExecOptionDoDefault)
        {
            if(commandName == "MyAddin1.Connect.MyAddin1")
            {
                handled = true;
                System.Windows.Forms.MessageBox.Show("Add-in ran.");
                return;
            }
        }
    }
    private DTE2 _applicationObject;
    private AddIn _addInInstance;
    }
}

Vea también

Tareas

Cómo: Cambiar el icono predeterminado de un complemento

Cómo: Exponer un complemento como un botón en la barra de herramientas

Conceptos

Mostrar complementos en barras de herramientas y menús