Visual Studio Tools for the Microsoft Office System
How to: Add Custom Icons to Toolbar and Menu Items

Note Required applications

The code example in this topic can be compiled only if you have the required applications installed.

For more information, see Features Available by Product Combination.

  • One of these development environments:

    VSTO 2005

    -or-

    Visual Studio Team System

  • Microsoft Office Outlook 2003

NoteNote

This code does not compile if you use the VSTO 2005 SE version of the Outlook 2003 add-in project template. For more information, see Getting Started Programming Application-Level Add-ins.

This example adds an icon to a command bar button on a custom menu in Microsoft Office Outlook 2003. The icon is included in the project resources. For more information about project resources, see Adding and Editing Resources (Visual C#) and How to: Add or Remove Resources.

To add custom icons

  1. Add code to the Outlook project's ThisApplication.vb or ThisApplication.cs file to create CommandBarPopup and CommandBarButton controls that represent the custom menu and menu command. This code checks to see whether the menu exists. If it does exist, this code removes the menu. It then adds the new menu.

    Visual Basic
    Private MenuBar As Office.CommandBar
    Private newMenuBar As Office.CommandBarPopup
    Private ButtonOne As Office.CommandBarButton
    Private menuTag As String = "AUniqueName"
    
    
    Private Sub ThisApplication_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup
        RemoveMenubar()
        AddMenuBar()
    End Sub
    
    Private Sub AddMenuBar()
        Try
            menuBar = Me.ActiveExplorer().CommandBars.ActiveMenuBar
            newMenuBar = menuBar.Controls.Add( _
                Office.MsoControlType.msoControlPopup, _
                Temporary:=False)
            If newMenuBar IsNot Nothing Then
                newMenuBar.Caption = "See New Icon"
                newMenuBar.Tag = menuTag
                buttonOne = newMenuBar.Controls.Add( _
                    Office.MsoControlType.msoControlButton, _
                    Before:=1, Temporary:=False)
                With buttonOne
                    .Style = Office.MsoButtonStyle _
                    .msoButtonIconAndCaption
                    .Caption = "New Icon"
                    .FaceId = 65
                    .Tag = "c123"
                    .Picture = getImage()
                End With
                newMenuBar.Visible = True
            End If
        Catch Ex As Exception
            MessageBox.Show(Ex.Message)
        End Try
    End Sub
    
    Private Sub RemoveMenubar()
        Try
            ' If the menu already exists, remove it.
            Dim foundMenu As Office.CommandBarPopup = _
                Me.ActiveExplorer().CommandBars.ActiveMenuBar. _
                FindControl(Office.MsoControlType.msoControlPopup, _
                System.Type.Missing, menuTag, True, True)
            If foundMenu IsNot Nothing Then
                foundMenu.Delete(True)
            End If
        Catch Ex As Exception
            MessageBox.Show(Ex.Message)
        End Try
    End Sub
    C#
    private Office.CommandBar menuBar;
    private Office.CommandBarPopup newMenuBar;
    private Office.CommandBarButton buttonOne;
    private string menuTag = "AUniqueTag";
    
    private void ThisApplication_Startup(object sender, System.EventArgs e)
    {
        RemoveMenubar();
        AddMenuBar();
    }
    
    private void AddMenuBar()
    {
        try
        {
            menuBar = this.ActiveExplorer().CommandBars.ActiveMenuBar;
            newMenuBar = (Office.CommandBarPopup)menuBar.Controls.Add(
                Office.MsoControlType.msoControlPopup, missing,
                missing, missing, false);
            if (newMenuBar != null)
            {
                newMenuBar.Caption = "See New Icon";
                newMenuBar.Tag = menuTag;
                buttonOne = (Office.CommandBarButton)
                    newMenuBar.Controls.
                Add(Office.MsoControlType.msoControlButton, System.
                    Type.Missing, System.Type.Missing, 1, true);
                buttonOne.Style = Office.MsoButtonStyle.
                    msoButtonIconAndCaption;
                buttonOne.Caption = "New Icon";
                buttonOne.FaceId = 65;
                buttonOne.Tag = "c123";
                buttonOne.Picture = getImage();
                newMenuBar.Visible = true;
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    
    private void RemoveMenubar()
    {
        // If the menu already exists, remove it.
        try
        {
            Office.CommandBarPopup foundMenu = (Office.CommandBarPopup)
                this.ActiveExplorer().CommandBars.ActiveMenuBar.
                FindControl(Office.MsoControlType.msoControlPopup,
                System.Type.Missing, menuTag, true, true);
            if (foundMenu != null)
            {
                foundMenu.Delete(true);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
  2. Create a new class named ConvertImage. This class uses System.Forms.Axhost to convert an Image file to an image type that can be applied to the menu item.

    Visual Basic
    Public Class ConvertImage
        Inherits System.Windows.Forms.AxHost
        Public Sub New()
            MyBase.New("59EE46BA-677D-4d20-BF10-8D8067CB8B32")
        End Sub
    
        Public Shared Function Convert(ByVal Image _
            As System.Drawing.Image) As stdole.IPictureDisp
            Convert = GetIPictureFromPicture(Image)
        End Function
    End Class
    C#
    sealed public class ConvertImage : System.Windows.Forms.AxHost
    {
        private ConvertImage()
            : base(null)
        {
        }
        public static stdole.IPictureDisp Convert
            (System.Drawing.Image image)
        {
            return (stdole.IPictureDisp)System.
                Windows.Forms.AxHost
                .GetIPictureDispFromPicture(image);
        }
    }
  3. Add a method to convert the icon file into an Image file by adding it to an ImageList. This code sends the Image file to the ConvertImage.Convert method you created and then returns the file to the caller.

    Visual Basic
    Private Function getImage() As stdole.IPictureDisp
        Dim tempImage As stdole.IPictureDisp = Nothing
        Try
            Dim newIcon As Icon = My.Resources.Icon1
            Dim newImageList As New ImageList
            newImageList.Images.Add(newIcon)
            tempImage = ConvertImage.Convert(newImageList.Images(0))
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
        Return tempImage
    End Function
    C#
    private stdole.IPictureDisp getImage()
    {
        stdole.IPictureDisp tempImage = null;
        try
        {
            System.Drawing.Icon newIcon = 
                Properties.Resources.Icon1;
    
            ImageList newImageList = new ImageList();
            newImageList.Images.Add(newIcon);
            tempImage = ConvertImage.Convert(newImageList.Images[0]);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        return tempImage;
    }

Compiling the Code

This example requires:

  • An icon named Icon1 in the project resources.

See Also

Tags :


Community Content

Dwz2006
Adding a Mask

If you want to also have a mask created the following code change creates a quick mask

        private void SetImage(CommandBarButton button, Icon newIcon)
{
try
{
ImageList newImageList = new ImageList();
newImageList.ColorDepth = ColorDepth.Depth8Bit;
newImageList.ImageSize = new Size(16, 16);
newImageList.Images.Add(newIcon);

button.Picture = ConvertImage.Convert(newImageList.Images[0]);

Bitmap mask = (Bitmap)newImageList.Images[0].Clone();
                for (int x = 0; x < 16; x++)
{
for (int y = 0; y < 16; y++)
{
mask.SetPixel(x,y, (mask.GetPixel(x, y) == Color.Transparent || mask.GetPixel(x,y).Name == "0") ?
                                            Color.White : Color.Black);
}
}
                button.Mask = ConvertImage.Convert(mask);
            }
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

Tags : 2005 vsto

iosys
Adding a Mask in VB.NET, accounting for semi-transparent pixels
Thanks to the previous comment I was able to understand how to use an image mask. I adapted the code to VB.NET and modified it to create a gray scale mask instead of just a black and white mask.

Public Class IPictureDisp
Inherits System.Windows.Forms.AxHost
Public Sub New()
MyBase.New("59EE46BA-677D-4d20-BF10-8D8067CB8B32")
End Sub

Public Shared Function FromImage(ByVal pImg As System.Drawing.Image) As stdole.IPictureDisp
Dim b As New Bitmap(16, 16)
Dim g As Graphics = Graphics.FromImage(b)
' fill the bitmap with white
g.FillRectangle(Brushes.White, 0, 0, 16, 16)
' draw the image over the white bitmap
g.DrawImage(pImg, 0, 0, 16, 16)
' return the opaque image
Return GetIPictureFromPicture(b)
End Function

Public Shared Function MaskFromImage(ByVal pImg As System.Drawing.Image) As stdole.IPictureDisp
Dim b As New Bitmap(16, 16)
Dim g As Graphics = Graphics.FromImage(b)
' draw the image over the transparent bitmap
g.DrawImage(pImg, 0, 0, 16, 16)
' convert pixels to grayscale
For x As Integer = 0 To 15
For y As Integer = 0 To 15
' get the pixel alpha
Dim pa As Integer
pa = b.GetPixel(x, y).A
' get the grayscale alpha equivalent of the pixel alpha
Dim pg As Integer
pg = 255 - pa
' replace the current pixel with a grayscale equivalent
b.SetPixel(x, y, Color.FromArgb(pg, pg, pg))
Next
Next
' return the picture
Return GetIPictureFromPicture(b)
End Function
End Class

To use the code, just do something like:

button.Picture = IPictureDisp.FromImage(my.resources.icon1)
button.Mask = IPictureDisp.MaskFromImage(my.resources.icon1)
Tags :

Page view tracker