방법: 추가 기능 단추에 사용자 지정 아이콘 표시

업데이트: 2007년 11월

추가 기능 옆에 표시되는 기본 아이콘(웃는 얼굴)을 방법: 추가 기능의 기본 아이콘 변경에 설명된 미리 정의된 표준 아이콘 이외의 아이콘으로 바꿀 수 있습니다.

다음과 같이 하면 됩니다.

  • 아이콘 비트맵을 위성 DLL 파일에 리소스로 배치합니다.

  • AddNamedCommand2 메서드의 MSOButton 매개 변수를 false로 설정하여 메서드가 위성 DLL에서 아이콘 비트맵을 찾도록 합니다.

  • 추가 기능 프로젝트의 명령 모음 부분에서 해당 리소스의 ID 번호를 참조합니다.

다음 절차에서는 추가 기능 단추에 사용자 지정 아이콘을 추가하는 방법을 보여 줍니다.

참고:

표시되는 대화 상자와 메뉴 명령은 실제 설정이나 버전에 따라 도움말에서 설명하는 것과 다를 수 있습니다. 이러한 절차는 일반 개발 설정을 사용하여 개발되었습니다. 설정을 변경하려면 도구 메뉴에서 설정 가져오기 및 내보내기를 선택합니다. 자세한 내용은 Visual Studio 설정을 참조하십시오.

추가 기능 프로젝트에 사용자 지정 비트맵을 추가 기능 단추 아이콘으로 추가하려면

  1. Visual Studio에서 기존 추가 기능 솔루션을 열거나 새 추가 기능 솔루션을 만듭니다.

    새 추가 기능을 만드는 경우 "추가 기능에 사용할 명령 모음 UI를 만드시겠습니까?" 옵션을 설정해야 합니다.

  2. 추가 기능 프로젝트에 새 리소스 파일을 추가합니다. 이를 위해 다음을 수행합니다.

    1. 솔루션 탐색기에서 추가 기능 프로젝트를 마우스 오른쪽 단추로 클릭합니다.

    2. 추가 메뉴에서 새 항목을 선택합니다.

    3. 템플릿 목록에서 리소스 파일을 선택하고 추가 단추를 클릭합니다. 기본 이름(Resources1.resx)은 그대로 둡니다.

      이렇게 하면 Visual Studio리소스 편집기가 시작됩니다.

  3. 솔루션 탐색기의 도구 모음에 있는 모든 파일 표시 단추를 클릭합니다.

  4. Resource1.resx의 속성에서 빌드 작업 속성을 없음으로 설정합니다.

    추가 기능에는 비트맵 인수로 정수 값이 필요합니다. 이 속성을 설정하면 리소스 파일을 편집하여 비트맵 리소스에 숫자 식별자를 지정할 수 있습니다. 이는 .resx 파일이 추가 기능 프로젝트의 일부인 경우에는 불가능합니다.

  5. 리소스 편집기에서 리소스 추가를 클릭한 다음 새 이미지 메뉴에서 BMP 이미지를 선택합니다. 지금은 기본 이름(Image1.bmp)을 그대로 둡니다.

    또는 크기가 16 x 16픽셀이고 16색 또는 트루 컬러인 기존 비트맵 이미지를 선택할 수도 있습니다. 추가 기능용 사용자 지정 아이콘은 크기가 16 x 16픽셀이어야 하고 16색 또는 트루 컬러여야 합니다.

  6. 비트맵 속성 창에서 높이와 너비 속성을 모두 16으로 변경합니다. 색 속성은 16색 또는 트루 컬러로 설정합니다.

  7. 새 비트맵을 만든 경우 리소스 편집기에서 그림을 편집합니다.

  8. 솔루션 탐색기에서 Resource1.resx 파일을 마우스 오른쪽 단추로 클릭하고 프로젝트에서 제외를 선택합니다.

    이를 통해 불필요한 컴파일러 오류를 막을 수 있습니다. 이 파일은 프로젝트에 포함될 필요가 없습니다. 이렇게 하면 기본 제공 리소스 편집기를 사용할 수 있습니다.

  9. 추가 기능의 Connect 클래스를 열고 AddNamedCommand2 줄의 OnConnection 메서드에서 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. Windows 탐색기에서 메모장을 사용하여 Resource1.resx 파일을 편집합니다.

  12. "Image1"이라는 문자열을 모두 찾아 "1"로 바꿉니다. 작업이 끝나면 파일을 저장합니다.

  13. 추가 기능의 \Resources 폴더에서 비트맵 파일 이름을 Image1.bmp에서 1.bmp로 변경합니다.

  14. ResGen 및 AL(어셈블리 링커)을 사용하여 위성 DLL을 빌드합니다. 이를 위해 다음을 수행합니다.

    1. 시작 메뉴에서 모든 프로그램, Microsoft Visual Studio 2005, Visual Studio Tools를 차례로 가리킨 다음 Visual Studio 2005 명령 프롬프트를 클릭합니다.

      이렇게 하면 특정 환경 변수가 설정되므로 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을 입력합니다.

      <Add-In Name>을 사용자의 추가 기능 이름으로 바꿉니다. 예를 들어 추가 기능 프로젝트의 이름이 MyAddin1인 경우 /out: 스위치는 /out:MyAddin1.resources.dll이 됩니다. /out: 이름이 프로젝트 이름과 일치하지 않으면 리소스 DLL을 찾지 못하게 됩니다.

      Al.exe(어셈블리 링커)는 지정한 .resources 파일을 사용자가 추가 기능에서 참조할 수 있는 위성 리소스 DLL로 변환합니다. /culture 스위치를 영어가 아닌 언어로 변경할 수 있습니다. 자세한 내용은 어셈블리 링커(Al.exe)를 참조하십시오.

  15. Windows 탐색기를 사용하여 추가 기능의 DLL 디렉터리(일반적으로 \bin 폴더)로 이동하고 Al의 culture 값으로 입력한 en-US라는 폴더를 만듭니다.

  16. <Add-In Name>.resources.dll 파일을 새 en-US 폴더로 복사합니다.

  17. Visual Studio에서 추가 기능 프로젝트를 다시 열고 실행합니다.

  18. 도구 메뉴를 클릭합니다.

    도구 메뉴에 사용자 지정 아이콘과 함께 추가 기능이 표시됩니다.

네이티브 C++ 추가 기능에 사용자 지정 비트맵을 추가 기능 단추 아이콘으로 추가하려면

  1. 위에서 설명한 것과 동일한 절차를 수행하되 다음과 같은 항목을 변경합니다.

  2. 새 Visual C++ Win32 DLL 프로젝트를 만듭니다.

  3. 리소스 파일(.rc)을 추가합니다.

  4. 리소스 뷰에서 비트맵(16 x 16)을 추가하고 숫자 ID를 부여합니다.

    비트맵은 크기가 16 x 16픽셀이어야 하고 16색 또는 트루 컬러여야 합니다.

  5. Connect.cpp의 AddNamedCommand2 메서드를 업데이트하여 MSOButton을 VARIANT_FALSE로, Bitmap을 앞서 할당한 비트맵 ID로 설정합니다.

  6. DLL을 빌드합니다.

  7. 네이티브 추가 기능 DLL 디렉터리에 "1033"(영어 로캘) 하위 폴더를 만듭니다.

  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"에서 경로에 로캘 ID를 추가하지 마십시오. 이는 런타임에 자동으로 추가됩니다.

  10. 추가 기능을 다시 빌드하여 업데이트된 정보를 등록합니다.

예제

다음은 위성 리소스 DLL에 포함된 사용자 지정 아이콘을 참조하는 Visual Basic/Visual C#/Visual J# 추가 기능의 전체 추가 기능 코드 예제입니다.

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

참고 항목

작업

방법: 추가 기능의 기본 아이콘 변경

방법: 추가 기능을 도구 모음의 단추로 표시

개념

도구 모음 및 메뉴에 추가 기능 표시