8 out of 49 rated this helpful - Rate this topic

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.

    
    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.

    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.

    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

Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
How to add transparent icons to msoControlButton?
I'm trying to load transparent icons to menubar in Access 2007 but no success. I'm stuck.

Public Function CreateCMenu_mnuFOakceNew()
    Dim cmb     As CommandBar
    Dim cmbBtn1 As CommandBarButton
    Dim cmbBtn2 As CommandBarButton
    Dim cmbBtn2a As CommandBarButton
    Dim cmbBtn3 As CommandBarButton
    Dim cmbBtn4 As CommandBarButton
   
    CommandBars("mnuFOakceNew").Delete
   
    Set cmb = CommandBars.add("mnuFOakceNew", msoBarPopup, False, False)
   
        With cmb
            Set cmbBtn1 = .Controls.add(msoControlButton, , , , True)
            With cmbBtn1
                .Picture = LoadPicture("C:\MyIcons\money.ico")
                .Caption = "Homebanking"
                .OnAction = "=fncImportHB()"
            End With
           
        End With

        .
        .

End Function

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