Build add-in for MS Office Excel , Word 2010 - 2000
in C++, C#, VB.NET: task panes, context menus, buttons

Add-in Express™
for Microsoft® Office and .net

Add-in Express Home > Add-in Express for Office and .NET > Online Guide > Building Office COM add-in

Building Office COM add-ins

Building COM add-ins for Outlook, Excel, Word in Visual Studio .NET - Flash video This page describes the general principles that Add-in Express .NET is based on. Here you fill find a step-by-step example of building a COM add-in for Excel, Word, PowerPoint or other applications from the Microsoft Office 2000 - 2010 suites in Visual Studio 2005, 2008 and 2010.

On other pages you will find some tips and tricks about:

Please keep in mind that Add-in Express provides special components for developing Outlook plug-ins, toolbars and menus. For more information please see a sample Outlook plug-in.

See the most recent video sample on Add-in Express blog:
How to create an Excel COM add-in in Visual Studio

Example of building an Office COM add-in

The sample add-in below for Microsoft Excel and Word is written in VB.NET, but you can use Add-in Express .NET to develop an Office add-in in Visual C#, Visual C++ and Delphi Prism as well. You may also want to find more about special features provided by Add-in Express for creating an advanced Excel GUI.

This VB.NET sample project implements a COM add-in for Excel, Word and PowerPoint versions 2000-2010.

Step 1. Creating a COM add-in project

Start Visual Studio via "Run as Administrator". Choose Add-in Express COM Add-in in the New Project dialog.

New Project dialog

Click OK to start the COM add-in project wizard. In the wizard, you choose the programming language of your add-in, as well as interop assemblies to use and Office applications to support in your add-in, see Choosing interop assemblies.

The project wizard creates and opens a new solution in the IDE. The solution contains an only project, the add-in project.

The add-in project contains the AddinModule.vb (or AddinModule1.cs) file discussed in the next step.

Add-in Express project wizard

Step 2. Add-in module

AddinModule.vb (or AddinModule1.cs) is the core part of the add-in project. It is a container for components essential for the functionality of your add-in. You specify the add-in properties in the module's properties, add the components to the module's designer, and write the functional code of your add-in in this module. To review its source code, in Solution Explorer, right-click the AddinModule1.vb (or AddinModule1.cs) file and choose View Code in the popup menu.

COM add-in module

The code for AddinModule1.vb is as follows:



Imports System.Runtime.InteropServices
Imports System.ComponentModel

'Add-in Express Add-in Module
<GuidAttribute("888782EF-544A-4EDD-8977-D24C4EE6F04D"), ProgIdAttribute("MyAddin1.AddinModule")> _
Public Class AddinModule
    Inherits AddinExpress.MSO.ADXAddinModule

#Region " Component Designer generated code. "
    'Required by designer
    Private components As System.ComponentModel.IContainer

    'Required by designer - do not modify
    'the following method
    Private Sub InitializeComponent()
        Me.components = New System.ComponentModel.Container()
        '
        'AddinModule
        '
        Me.AddinName = "MyAddin1"

        Me.SupportedApps = CType(( _
                        AddinExpress.MSO.ADXOfficeHostApp.ohaExcel Or _
                        AddinExpress.MSO.ADXOfficeHostApp.ohaWord Or _
                        AddinExpress.MSO.ADXOfficeHostApp.ohaPowerPoint  _
                        ), AddinExpress.MSO.ADXOfficeHostApp)
    End Sub

#End Region

#Region " Add-in Express automatic code "

    'Required by Add-in Express - do not modify
    'the methods within this region

    Public Overrides Function GetContainer() As System.ComponentModel.IContainer
        If components Is Nothing Then
            components = New System.ComponentModel.Container
        End If
        GetContainer = components
    End Function

    <ComRegisterFunctionAttribute()> _
    Public Shared Sub AddinRegister(ByVal t As Type)
        AddinExpress.MSO.ADXAddinModule.ADXRegister(t)
    End Sub

    <ComUnregisterFunctionAttribute()> _
    Public Shared Sub AddinUnregister(ByVal t As Type)
        AddinExpress.MSO.ADXAddinModule.ADXUnregister(t)
    End Sub

    Public Overrides Sub UninstallControls()
        MyBase.UninstallControls()
    End Sub

#End Region

    Public Sub New()
        MyBase.New()

        'This call is required by the Component Designer
        InitializeComponent()

        'Please add any initialization code to the AddinInitialize event handler

    End Sub

    Public ReadOnly Property ExcelApp() As Excel._Application
        Get
            Return CType(HostApplication, Excel._Application)
        End Get
    End Property

    Public ReadOnly Property PowerPointApp() As PowerPoint._Application
        Get
            Return CType(HostApplication, PowerPoint._Application)
        End Get
    End Property

    Public ReadOnly Property WordApp() As Word._Application
        Get
            Return CType(HostApplication, Word._Application)
        End Get
    End Property

End Class



Pay attention to the ExcelApp, PowerPointApp and WordApp properties of the module generated by the wizard. You use them in your code to access the object model(s) of the host application(s) of your add-in.

Step 3. Add-in module designer

The designer of the add-in module allows setting add-in properties and adding components to the module.

In Solution Explorer, right-click the AddinModule.vb (or AddinModule.cs) file and choose View Designer in the popup menu.

COM Add-in designer

In the Properties window, you set the name and description of your add-in.

Addin module properties

To add an Add-in Express component to the module, choose an appropriate command in the Commands Toolbar, or you can right-click the designer surface and choose the same command in the context menu. See also Add-in Express Module basics and Commands of the Add-in Module.

Step 4. Adding a new toolbar

To add a toolbar to your add-in, you use the Add ADXCommandBar button. It adds an ADXCommandBar component to the add-in module.

Adding a CommandBar component to the add-in module

Select the command bar component and, in the Properties window, specify the toolbar name in the CommandBarName property.

If the toolbar name is not the same as the name of any built-in command bar of the host application, then the component will create a new toolbar at run-time. That is, if you set CommandBarName = "Standard", and add, say, an ADXCommandBarButton to the Controls collection of the ADXCommandBar component, this will create a button on the built-in Standard toolbar, while specifying CommandBarName = "Standard2" will create a new toolbar, Standard2, with a button on it. If the Standard2 toolbar is already present in the host application, the button will be added to that toolbar.

See also Command Bars: toolbars, menus, and context menus and Command bars in the Ribbon UI.

Step 5. Adding a new toolbar button

Select the command bar component on the designer of the add-in module and open the in-place designer area. In this area, you'll see the visual designer of the ADXCommandBar component. Use its toolbar to add or remove command bar controls. Just click the appropriate button and see the result.

Adding a new button to an MS Office toolbar

In the screenshot above, a toolbar button is already added. Now, select the button and open the Properties window where you specify the button's Caption property, change the Style property if you need to show an icon on the button (default value = adxMsoButtonCaption), and add an event handler to the Click event.

In the screenshot on the right, we demonstrate the button properties that make the icon visible and transparent: Style, Image, ImageList and ImageTransparentColor.

Step 6. Accessing host application objects

The add-in module provides the HostApplication property that returns the Application object (of the Object type) of the host application the add-in is currently running in. For your convenience, the project wizard adds host-related properties to the module such as ExcelApp, WordApp, etc. You use these properties as entry points to the host applications object models. See how these properties are used in the code below:


   Private Sub DefaultAction(ByVal sender As System.Object) _
    Handles AdxCommandBarButton1.Click
    MsgBox(GetInfoString())
End Sub

Friend Function GetInfoString() As String
    Dim ActiveWindow As Object = Nothing
    Try
        ActiveWindow = Me.HostApplication.ActiveWindow() 'late binding
    Catch
    End Try
    Dim Result As String = "No document window found!"
    If Not ActiveWindow Is Nothing Then
        Select Case Me.HostType
            Case ADXOfficeHostApp.ohaExcel
                Dim ActiveCell As Excel.Range = _
                    CType(ActiveWindow, Excel.Window).ActiveCell
                If ActiveCell IsNot Nothing Then
                    'relative address
                    Dim Address As String = ActiveCell.AddressLocal(False, False)
                    Marshal.ReleaseComObject(ActiveCell)
                    Result = "The current cell is " + Address
                End If
            Case ADXOfficeHostApp.ohaWord
                Dim Selection As Word.Selection = _
                    CType(ActiveWindow, Word.Window).Selection
                Dim Range As Word.Range = Selection.Range
                Dim Words As Word.Words = Range.Words
                Dim WordCountString = Words.Count.ToString()
                Marshal.ReleaseComObject(Selection)
                Marshal.ReleaseComObject(Range)
                Marshal.ReleaseComObject(Words)
                Result = "There are " + WordCountString _
                    + " words currently selected"
            Case ADXOfficeHostApp.ohaPowerPoint
                Dim Selection As PowerPoint.Selection = _
                    CType(ActiveWindow, PowerPoint.DocumentWindow).Selection
                Dim SlideRange As PowerPoint.SlideRange = Selection.SlideRange
                Dim SlideCountString = SlideRange.Count.ToString()
                Marshal.ReleaseComObject(Selection)
                Marshal.ReleaseComObject(SlideRange)
                Result = "There are " + SlideCountString _
                    + " slides currently selected"
            Case Else
                Result = AddinName + " doesn't support " + HostName
        End Select
        Marshal.ReleaseComObject(ActiveWindow)
    End If
    Return Result
End Function

Two things in the code above deserve your attention. First, the GetInfoString method will be called from a number of events. If this code is run in Word and there is no open document, Me.HostApplication.ActiveWindow() will fire an exception. That is why this code line is wrapped in a try/catch block. Second, you have to release every COM object created in your code. See Releasing COM objects for more details.

Step 7. Customizing main menus

Add-in Express provides a component to customize the main menu of any Office application. Note that several Office applications from Office 2000-2003 have several main menus. Say, in these Excel versions, you find Worksheet Menu Bar and Chart Menu Bar. Naturally, in Excel 2007 and 2010 these menus are replaced with the Ribbon UI. Nevertheless, they are still accessible programmatically and you may want to use this fact in your code. As for customizing main menus in Outlook, see Developing Microsoft Outlook COM add-in.

Setting up the main menu component

In this sample, we are going to customize the File menu in Excel and Word, version 2000-2003. You start with adding two main menu components and specifying correct host applications in their SupportedApp properties. Then, in the CommandBarName property, you specify the main menu.

The screenshot on the right shows how you set up the main menu component in order to customize the Worksheet Menu Bar main menu in Excel 2000-2003.

Now you can open the in-place designer for the main menu component and populate it with controls. First off, you add a popup control and set its Id property to 30002. Specifying anything but 1 in this property means that controls added to that ADXCommandBarPopup component, will be created on the built-in popup control having ID=30002, which is the ID of the File menu item in Office applications. To find this and similar IDs, use our free Built-in Control Scanner. See also Connecting to existing commandBar controls.

In-place designer for the main menu component

Then you add a button and set their properties in the way described in Step 5. Adding a New Toolbar Button. Pay attention to the BeforeID property of the button. To place the button before the New button, you set this property to 3, which is the ID of the button New. Please remember that showing an image for any command bar control requires choosing a correct value for the Style property of the button. For the newly added menu item (button) set Style = adxMsoButtonIconAndCaption.

Note that Office imposes restrictions on controls that can be added onto a main menu: the only control types available are command bar button and command bar popup.

See also Step 11. Customizing the Ribbon user interface for customizing the Office button menu in Office 2007 and the File tab in Office 2010.

Step 8. Customizing context menus

Add-in Express allows customizing commandbar-based context menus in Office 2000-2010 with the ADXContextMenu component. Its use is similar to that of the ADXMainMenu component. See how to set up such a component to add a custom button to the Cell context menu in Excel:

  • Add a context menu component to the add-in module
  • Specify the host application, the context menu of which you need to customize
  • Specify the context menu to customize
  • Use the in-place designer to add custom controls to the Controls collection of the component

Setting the Context Menu component

Context menu designer

You may want to use the BeforeAddControls event provided by the component to modify the context menu depending on the current context. Say, custom controls in the context menu may reflect the content of an Excel cell, the current chapter of the Word document, etc.

There are several issues related to using command bar based context menus:

  • Excel contains two different context menus named Cell. This fact breaks down the command bar development model because the only way to recognize two command bars is to compare their names. This isn't the only exception: use our Built-in Control Scanner to find a number of examples. In this case, the context menu component cannot distinguish context menus. Accordingly, it connects to the first context menu of the name specified by you.
  • Command bar based context menu items cannot be positioned in the Ribbon-based context menus: a custom context menu item created with the ADXContextMenu component will always be shown below the built-in and custom context menu items in a Ribbon-based context menu of Office 2010.

To add a custom item to a context menu in Office 2010, you use the ADXRibbonContextMenu component. Unlike its commandbar-based counterpart (ADXContextMenu), this component allows adding custom Ribbon controls to several context menus in the specified Ribbons. The screenshots below demonstrate component settings required for adding a control to the ExcelWorkbook Ribbon. To specify the context menus, to which the control will be added, you use the editor of the ContexMenuNames property of the component.

Ribbon context menu properties

Ribbon context menu names

Step 9. Handling host application events

The add-in module designer provides the Add Events command that adds (and removes) event components that allow handling application-level events (see Application-level events).

Selecting event components

With the event components, you handle any application-level events of the host application. Say, you may want to disable the button when a window deactivates and enable it when a window activates. The code is as follows:


   Private Sub Deactivate(ByVal sender As Object, _
      ByVal hostObj As Object, ByVal window As Object) _
      Handles adxWordEvents.WindowDeactivate, _
          adxExcelEvents.WindowDeactivate, _
          adxPowerPointEvents.WindowActivate
      Me.AdxCommandBarButton1.Enabled = False
   End Sub

   Private Sub Activate(ByVal sender As Object, ByVal hostObj As Object, _
      ByVal window As Object) _
      Handles adxWordEvents.WindowActivate, _
          adxExcelEvents.WindowActivate, _
          adxPowerPointEvents.WindowDeactivate
      Me.AdxCommandBarButton1.Enabled = True
   End Sub

Step 10. Handling Excel worksheet events

Add-in Express provides the Excel Worksheet Events template item (see Add New Item dialog) that allows implementing a set of business rules for an Excel worksheet by handling its events.

Excel Worksheet event template

This will add an event class to your project.

Excel worksheet event class

In the event class, you add the following code to the procedure that handles the BeforeRightClick event of the Worksheet class:


   Public Overrides Sub ProcessBeforeRightClick(ByVal Target As Object, _
         ByVal E As AddinExpress.MSO.ADXCancelEventArgs)
      Dim R As Excel.Range = CType(Target, Excel.Range)
      'Cancel right-clicks for the first column only
      If R.Address(False, False).IndexOf("A") = 0 Then
         MsgBox("Context menu will not be shown!")
         E.Cancel = True
      Else
         E.Cancel = False
      End If
   End Sub

In addition, you modify the Activate and Deactivate procedures as follows:


   Dim MyEventClass As ExcelWorksheetEventsClass1 = _
       New ExcelWorksheetEventsClass1(Me)
...
Private Sub Deactivate(ByVal sender As Object, ByVal hostObj As Object, _
   ByVal window As Object) _
   Handles adxWordEvents.WindowDeactivate, adxExcelEvents.WindowDeactivate
   Me.AdxCommandBarButton1.Enabled = False
   Select Case Me.HostName
      Case "Excel"
         If MyEventClass.IsConnected Then MyEventClass.RemoveConnection()
      Case "Word"
      Case "PowerPoint"
      Case Else
         MsgBox(Me.AddinName + " doesn't support " + Me.HostName)
   End Select
End Sub

Private Sub Activate(ByVal sender As Object, ByVal hostObj As Object, _
   ByVal window As Object) _
   Handles adxWordEvents.WindowActivate, adxExcelEvents.WindowActivate
   Me.AdxCommandBarButton1.Enabled = True
   Select Case Me.HostName
      Case "Excel"
         If MyEventClass.IsConnected Then MyEventClass.RemoveConnection()
         MyEventClass.ConnectTo(Me.ExcelApp.ActiveSheet, True)
      Case "Word"
      Case "PowerPoint"
      Case Else
         MsgBox(Me.AddinName + " doesn't support " + Me.HostName)
   End Select
End Sub


Step 11. Customizing the Ribbon User interface

To add a new tab to the Ribbon, you use the Add Ribbon Tab command that adds an ADXRibbonTab component to the module. In the in-place visual designer, use toolbar buttons or context menu to add or delete Add-in Express components that form the Ribbon interface of your add-in.

In this sample, you change the caption of your tab to My Ribbon Tab. Then, you add a Ribbon group, and change its caption to My Ribbon Group. Next, you add a button group. Finally, you add a button and set its caption to My Ribbon Button. Use the ImageList and Image properties to set the image for the button.

Ribbon Tab component

Now add the event handler to the Click event of the button. Write the following code:


    Private Sub AdxRibbonButton1_OnClick(ByVal sender As System.Object, _
        ByVal control As AddinExpress.MSO.IRibbonControl, _
        ByVal pressed As System.Boolean) Handles AdxRibbonButton1.OnClick
        AdxCommandBarButton1_Click(Nothing)
    End Sub

Remember, the Ribbon Tab designer validates the XML-markup automatically, so from time to time you will run into the situation when you cannot add a control to some level. It is a restriction of the Ribbon XML-schema.

In the code of this sample add-in, you can find how you can customize the Office Button menu in Office 2007, see component named AdxRibbonOfficeMenu1. As to the Backstage View, also known as the File Tab in Office 2010, the sample project provides the AdxBackstageView1 component that implements the customization shown in Figure 3 at Introduction to the Office 2010 Backstage View for Developers. Note, if you customize the Office Button menu only, Add-in Express maps your controls to the Backstage View when the add-in is loaded by Office 2010. If, however, both Office Button menu and File tab are customized at the same time, Add-in Express ignores custom controls you add to the Office Button menu. See also Ribbon Components.

Step 12. Adding custom task panes in Excel 2000-2010

Creating a new Excel task pane includes the following steps:

  • add an Excel Task Panes Manager (ADXExcelTaskPanesManager) to your add-in module
  • add an Add-in Express Excel Task Pane (ADXExcelTaskPane) to your project
  • add an item to the Items collection of the manager, choose the pane just added in the TaskPaneClassName property of the item and set other properties, such as Position in the screenshot below.

Custom Excel task pane settings

The properties shown on the screenshot above are:

  • AlwaysShowHeader - specifies that the pane header will be shown even if the pane is the only pane in the current region.
  • CloseButton - specifies if the Close button will be shown in the pane header. Obviously, there's not much sense in setting this property to true when the header isn't shown.
  • Position - specifies the region in which an instance of the pane will be shown. Excel panes are allowed in four regions docked to the four sides of the main Excel window: Right, Bottom, Left, and Top. The fifth region is Unknown.
  • TaskPaneClassName - specifies the class name of the Excel task pane.

Now you add a label onto the form and change its caption in the following code:

Private Sub RefreshTaskPane()
    Private Sub RefreshTaskPane()
    Select Case Me.HostName
        Case "Excel"
            Dim Pane As ADXExcelTaskPane1 = _
                TryCast(Me.AdxExcelTaskPanesCollectionItem1.TaskPaneInstance, _
                    ADXExcelTaskPane1)
            If Pane IsNot Nothing Then
                Pane.Label1.Text = Me.GetInfoString()
            End If
        Case "Word"
        Case "PowerPoint"
        Case Else
            'System.Windows.Forms.MessageBox.Show("Invalid host application!")
    End Select
End Sub

See also Advanced Custom Task Panes

Step 13. Adding custom task panes in PowerPoint 2000-2010

Now you add a PowerPoint task pane:

  • add a PowerPoint Task Panes Manager (ADXPowerPointTaskPanesManager) to your add-in module
  • add an Add-in Express PowerPoint Task Pane (ADXPowerPointTaskPane) to your project (see Add New Item dialog)
  • in the visual designer available for the Controls collection of the manager, add an item to the collection, bind the pane to the item and specify an appropriate value in the Position.

Now add a label onto the form, write a property that reads and updates the label, and update RefreshTaskPane in order to set the property value:


Private Sub RefreshTaskPane()
    Select Case Me.HostName
        Case "Excel"
...
        Case "Word"
        Case "PowerPoint"
            Dim Pane As ADXPowerPointTaskPane1 = _
                TryCast( _
                    Me.AdxPowerPointTaskPanesCollectionItem1.TaskPaneInstance, _
                    ADXPowerPointTaskPane1)
            If Pane IsNot Nothing Then
                Pane.Label1.Text = Me.GetInfoString()
            End If
        Case Else
            'System.Windows.Forms.MessageBox.Show("Invalid host application!")
    End Select
End Sub

See also Advanced custom task panes for PowerPoint.

Step 14. Adding custom task panes in Word 2000-2010

You add a Word task pane in the same manner:

  • add a Word Task Panes Manager (ADXWordTaskPanesManager) to your add-in module
  • add an Add-in Express Word Task Pane (ADXWordTaskPane) to your project
  • in the visual designer available for the Controls collection of the manager, add an item to the collection, bind the pane to the item and specify an appropriate value in the Position.

Now add a label onto the form and update RefreshTaskPane in order to set the label:


Private Sub RefreshTaskPane()
    Select Case Me.HostName
        Case "Excel"
...
        Case "Word"
            Dim Pane As ADXWordTaskPane1 = _
                TryCast( _
                    Me.AdxWordTaskPanesCollectionItem1.CurrentTaskPaneInstance, _
                    ADXWordTaskPane1)
            If Pane IsNot Nothing Then
                Pane.Label1.Text = Me.GetInfoString()
            End If
        Case "PowerPoint"
...
        Case Else
            'System.Windows.Forms.MessageBox.Show("Invalid host application!")
    End Select
End Sub

The different names of the properties returning instances of the three pane types reflect the difference in Excel, PowerPoint and Word windowing; while Excel and PowerPoint show their documents in just one main window, Word normally shows documents in multiple windows. In this situation, the Word Task Panes Manager creates one instance of the pane for every document open in Word. Therefore, you need to handle the task pane instance, which is currently active. For that reason, the property name is CurrentTaskPaneInstance. See also Advanced custom task panes for Word.

Step 15. Running the COM Add-in

Choose Register Add-in Express Project in the Build menu (if you use the Express edition of Visual Studio, this item can be found in the context menu of the add-in module's designer surface), and restart the host applications.

Running an Excel COM add-in

Running a PowerPoint COM add-in

Running a Word COM add-in

You can also find your add-in in the COM Add-ins dialog.

Step 16. Debugging the COM add-in

To debug your add-in, in the Project Options window, specify the path to the host application of the add-in in Start External Program and run the project.

Debugging a COM add-in

Step 17. Deploying the COM add-in

Create a setup project, build it, copy all setup files to the target PC and run the installer (see Deploying Office extensions).

Creating setup project

find more about:

Developing custom Outlook forms <<

>> Writing Outlook COM add-ins

Back to Add-in Express for Office and .NET homepage