Поделиться через


Практическое руководство. Отображение пользовательского значка на кнопке надстройки

Обновлен: Ноябрь 2007

Значок по умолчанию (смайлик), отображаемый рядом с командой надстройки, можно заменить значком не из числа предварительно определенных стандартных значков, как описано в разделе Практическое руководство. Изменение значка по умолчанию для надстройки.

Процесс замены заключается в следующем:

  • Размещение растрового изображения значка в виде ресурса в файле вспомогательной библиотеки DLL.

  • Установка параметра MSOButton в методе AddNamedCommand2 равным false (метод будет выполнять поиск растрового изображения значка во вспомогательной библиотеке DLL).

  • Создание ссылки на номер этого ресурса в разделе commandbar проекта надстройки.

В следующей процедуре описан порядок добавления пользовательского значка к кнопке надстройки.

ms228771.alert_note(ru-ru,VS.90).gifПримечание.

Отображаемые диалоговые окна и команды меню могут отличаться от описанных в справке в зависимости от текущих параметров или выпуска. Эти процедуры были разработаны с обычными параметрами разработки. Чтобы изменить настройки, в меню Сервис выберите команду Импорт и экспортпараметров. Дополнительные сведения см. в разделе Параметры Visual Studio.

Чтобы добавить пользовательский растровый рисунок как значок кнопки надстройки в проект надстройки

  1. Откройте существующее решение надстройки или создайте новое решение в Visual Studio.

    При создании новой надстройки установите флажок "Создать интерфейс панели команд для надстройки?".

  2. Добавьте новый файл ресурсов в проект надстройки. Чтобы сделать это:

    1. Щелкните правой кнопкой мыши проект надстройки в Обозревателе решений.

    2. В меню Добавить выберите команду Новый элемент.

    3. В списке шаблонов выберите Файл ресурсов и нажмите кнопку Добавить. Примите имя по умолчанию (Resources1.resx).

      Запустится Редактор ресурсов Visual Studio.

  3. В панели инструментов Обозревателя решений нажмите кнопку Показать все файлы.

  4. В свойствах Resource1.resx присвойте свойству Действие при построении значение “Нет”.

    В качестве аргумента растрового рисунка для надстройки должно быть указано целое число. Установка этого свойства позволит редактировать файл ресурсов и назначить точечному ресурсу числовой идентификатор в качестве имени, чего нельзя сделать, когда файл RESX является частью проекта надстройки.

  5. В Редакторе ресурсов щелкните Добавить ресурс, а затем в меню Новое изображение выберите Изображение BMP. Пока примите его имя по умолчанию (Image1.bmp).

    Можно также выбрать существующее растровое изображение размером 16 x 16 точек и с глубиной цвета 16 цветов или True Color. Пользовательские значки для надстроек должны иметь размер 16 x 16 точек и глубину цвета 16 цветов или True Color.

  6. В окне свойств растрового изображения измените свойства Высота и Ширина на значение 16. Свойству Цвета присвойте значения 16 цветов или True Color.

  7. Если создано новое растровое изображение, измените рисунок в Редакторе ресурсов.

  8. Щелкните правой кнопкой мыши файл Resource1.resx в Обозревателе решений и выберите команду Исключить из проекта.

    Таким образом можно будет предотвратить ненужные ошибки. Файл не обязательно должен быть в проекте. Это позволит использовать встроенный Редактор ресурсов.

  9. Откройте класс Connect для надстройки. В методе OnConnection в строке AddNamedCommand2 измените значение параметра MSOButton с true на false, а значение параметра Bitmap с 59 на 1. Пример.

    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);
    

    Если аргументу MSOButton присвоить значение “false”, надстройка будет выполнять поиск файла ресурса для изображения ее кнопки. Число 1 будет идентификатором этого растрового изображения. (Это будет сделано позднее.)

  10. Когда все готово, в меню Файл выберите команду Сохранить все, в меню Построение выберите Построить решение, а затем закройте решение.

  11. Для редактирования файла Resource1.resx в Проводнике Windows откройте Блокнот.

  12. Найдите все экземпляры "Image1" и измените их на "1". После этого сохраните файл.

  13. В папке \Resources для надстройки измените имя файла растрового изображения с Image1.bmp на 1.bmp.

  14. Для построения вспомогательной библиотеки DLL используйте ResGen и компоновщик сборок (AL). Чтобы сделать это:

    1. В меню Пуск укажите Все программы — Microsoft Visual Studio 2005 — Visual Studio Tools и щелкните Командная строка Visual Studio.

      Это позволит задать определенные переменные среды так, чтобы можно было с легкостью создавать ссылки на инструменты Visual Studio.

    2. В командной строке перейдите к папке с файлом RESX и наберите Resgen Resource1.resx.

      Resgen — это служебная программа, компилирующая указанный файл RESX в файл RESOURCES. Дополнительные сведения см. в разделе Генератор файлов ресурсов (Resgen.exe).

    3. Теперь в командной строке наберите следующее: Al.exe /embed:Resource1.resources /culture:en-US /out:<Add-In Name>.resources.dll.

      Замените <Имя_надстройки> именем своей надстройки. Например, если проект надстройки имеет имя MyAddin1, то оператор /out: следует добавить так, чтобы получилось /out:MyAddin1.resources.dll. Если имя оператора /out: не совпадает с именем проекта, то библиотека ресурсов DLL найдена не будет.

      Компоновщик сборок (Al.exe) преобразует указанный файл RESOURCES во вспомогательную DLL-библиотеку ресурсов, на которую можно будет создать ссылку в надстройке. (В переключателе /culture можно указать не только английский язык). Дополнительные сведения см. в разделе Компоновщик сборок (Al.exe).

  15. В Проводнике Windows перейдите к каталогу с DLL надстройки (обычно это папка \bin) и создайте папку с именем en-US (для английского языка (США), так как в качестве языка в средстве Al было указано en-US).

  16. Скопируйте файл <Имя_надстройки>.resources.dll в новую папку en-US.

  17. Откройте проект в Visual Studio еще раз и запустите его.

  18. Выберите меню Сервис.

    Надстройка появится в меню Сервис вместе с пользовательским значком.

Чтобы добавить пользовательское растровое изображение как значок встроенной надстройки Visual C++

  1. Выполните описанные выше действия, но измените следующие элементы.

  2. Создайте новый проект DLL Win32 Visual C++.

  3. Добавьте файл ресурсов (RC).

  4. В представлении ресурсов добавьте растровое изображение (16 x 16) и присвойте ему числовой идентификатор.

    Точечный рисунок должен иметь размер 16 x 16 точек и глубину цвета 16 цветов или True Color.

  5. Обновите метод AddNamedCommand2 в Connect.cpp, изменив MSOButton на VARIANT_FALSE и указав в Bitmap идентификатор назначенного ранее растрового изображения.

  6. Постройте библиотеку DLL.

  7. Создайте вложенную папку "1033" (для английского языка) в каталоге со встроенной библиотекой DLL.

  8. Скопируйте вспомогательную библиотеку DLL в каталог "1033".

  9. Откройте AddIn.rgs и добавьте два значения разделов реестра "SatelliteDllName" и "SatelliteDllPath". Пример.

    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'
                         }
                      }
                   }
                }
             }
          }
       }
    

    Не добавляйте код языка в пути в "SatelliteDllPath". Код языка будет добавлен автоматически во время выполнения.

  10. Выполните построение надстройки еще раз для регистрации обновленных сведений.

Пример

Ниже приводится полный пример кода надстройки для надстройки Visual Basic/Visual C#/Visual J#, ссылающейся на пользовательский значок, содержащийся во вспомогательной DLL-библиотеке ресурсов.

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;
    }
}

См. также

Задачи

Практическое руководство. Изменение значка по умолчанию для надстройки

Практическое руководство. Вывод надстройки в виде кнопки на панели инструментов

Основные понятия

Отображение надстроек в панелях инструментов и меню