Developing COM Add-Ins for Microsoft Office 2000

This content is no longer actively maintained. It is provided as is, for anyone who may still be using these technologies, with no warranties or claims of accuracy with regard to the most recent product version or service release.

 

Ed Schultz
Microsoft Corporation

Revision Date: January 1999

Contents

Design Goals Add-In Designer IDTExtensibility2 Interface Add-In Object Model COMAddIn Object CommandBar Customizations Add-In Registration Debugging Worldwide, Localization, Far East

For the most current information, see https://msdn.microsoft.com/office.

The Microsoft Visual Studio® 6.0 development system (containing Microsoft® Visual Basic®, Visual C++®, and Visual J++®) is the main, professional development tool and environment for creating custom solutions for use with Microsoft Word, Excel, PowerPoint®, Access, Outlook®, or a combination of any of the applications in Microsoft® Office 2000.

Microsoft Office 2000 provides an extensibility interface that can be exposed by add-ins created in Visual Basic, Visual C++, or Visual J++ in order to connect to and disconnect from any Office host application.

Design Goals

Because of the new extensibility interface in Office 2000, developers can now develop solutions for Office 2000 with any language that can create Component Object Model (COM) components. In addition, these add-ins all use the same extensibility model and user interface to connect and disconnect to any and all Office host applications. Office now has one unified development environment and add-in model.

Developing application extensions for Microsoft Office 2000 using COM has many distinct advantages. In addition, Visual Studio 6.0 provides a number of tools that are currently not provided in the Visual Basic for Applications (VBA) environment.

Specific design goals include:

  • COM DLL Connection: Common, consistent Visual Studio 6.0 extensibility architecture for loading COM add-ins within Office applications. In Office 97, an Office application has to load a VBA add-in in order to load a COM DLL. The VBA add-in references the COM DLL within its auto open routine or open event, and the VBA add-in sets a public reference to a class in the COM DLL. In Office 2000, the Office application loads a COM DLL through the same connection architecture as Visual Studio 6.0 and thus removes the dependency on using VBA add-ins as a connection between COM DLLs and Office applications.
  • UI Connection: The ability to connect the OnAction property of command bar controls to procedures in COM add-ins.
  • Deployment: Solutions are easily packaged and installed on the user's system.
  • Add-In Templates: Office 2000 Developer installs a set of project templates for Office application-specific solutions or Office-wide solutions. Samples have been developed for all languages and tools shipped in the Visual Studio 6.0 IDE that can develop COM components; currently Visual Basic, Visual C++, and Visual J++.

Add-In Designer

Visual Studio 6.0 introduces an add-in registration mechanism that improves the add-in user's experience. The new mechanism also provides flexibility for future enhancements. Visual Basic and Visual Studio improve the add-in authoring experience and better support the new registration mechanism by creating add-ins that auto-register via the DllRegisterServer entry point. Office 2000 uses the same solution for the Office 2000 add-ins.

Historically, Visual Basic developers have not had a means for Visual Basic components to register application-specific data on DLLRegisterServer (and remove the data when unregistering). The new public designers feature exposes new functionality that allows a designer to contribute application-specific registry data to a delivered component, and the component's DLLRegisterServer entry point can install this data.

Solution: Visual Studio provides an Add-In Designer that allows the add-in author to set properties at design time, and that provides the entry-point class for any add-in. The Add-In Designer's run-time component supports IDT_Extensibility2 externally and exposes this interface as Visual Basic events to the add-in (and the add-in author at development time). The designer has several very simple properties that allow the developer to specify whether the add-in is to register as an auto-load add-in or to participate in specific component categories. The designer provides the required registry information to the run time using the new technology developed in Visual Basic 6.0.

IDTExtensiblity2 Interface

The IDTExtensibility2 interface contains methods that Office calls when an add-in is connected to an Office application, whether through the Add-Ins dialog box or some other manner. The IDTExtensibility2 interface contains pre-configured procedure templates (which include their parameter lists) that you need to manage add-ins in Office.

Description

It is important to note that, for each of the methods described for the IDTExtensibility2 interface, you—as the Office developer—do not directly enter the syntax given below in Visual Basic. Instead, use the Implements statement to generate the appropriate method template for the interface. To do this, in the Declarations section of the Class module that provides the add-in's connection object, enter:

Implements IDTExtensibility2

After adding this line, you can then select IDTExtensibility2 from the module's Object drop-down box. Select each method from the Procedure box to get the procedure template shown above in Syntax. Notice that the necessary code is automatically added to the Class module.

An interface's methods are exposed through the Implements statement. When the above syntax is entered in the Declarations section of the Class module that handles an add-in's events, the interface's methods become available for use through the module's Procedure and Object drop-down boxes. To add the code to the module, select the method from the Procedure box.

Syntax

Implements IDTExtensiblity2

Remarks

The usage of interfaces is new to Office 2000. Interfaces enable you to choose a pre-configured procedure template from a module's Procedure drop-down list, eliminating parameter list entry errors and allowing you to program your applications a bit faster.

An interface's methods are exposed through the Implements statement. When the above syntax is entered in the Declarations section of the Class module that handles an add-in's events, the interface's methods become available for use through the module's Procedure and Object drop-down boxes in Visual Basic. To add the code to the module, simply select it from the drop-down box.

The IDTExtensibility2 interface currently contains five methods:

  • OnAddInsUpdate
  • OnBeginShutdown
  • OnConnection
  • OnDisconnection
  • OnStartupComplete

While these are methods to the IDTExtensibility2 interface, to a Visual Basic programmer they act and behave like events. In other words, when an add-in is connected to Office, the OnConnection method is called automatically, similar to an event firing. When it is disconnected, the OnDisconnection method is called automatically, and so forth.

Important Note: Because an interface is a contract between an object and Office, be sure to implement all methods in the interface. This means that all five IDTExtensibility2 interface methods are present in your Class module, each containing at least one executable statement. This can consist of as little as a single remark statement, but each must contain at least one executable statement to prevent the compiler from removing them as empty procedures.

The IDTExtensibility2 interface and associated enums are provided in the type library: MSADDNDR.tlb. It is a type library built and shipped by Visual Studio 6.0, and it is shared among any Microsoft applications that use IDTExtensibility2 for their add-in architecture.

ODL Syntax

    interface IDTExtensibility2 : IDispatch {
        [id(1)] HRESULT OnConnection(
            [in] Object* HostApp, 
            [in] long ext_ConnectMode, 
            [in] IDispatch* AddInInst, 
            [in] SAFEARRAY(VARIANT)* custom);
        [id(2)] HRESULT OnDisconnection(
            [in] long ext_DisconnectMode, 
            [in] SAFEARRAY(VARIANT)* custom);
        [id(3)] HRESULT OnAddInsUpdate([in] SAFEARRAY(VARIANT)* custom);
        [id(4)] HRESULT OnStartupComplete([in] SAFEARRAY(VARIANT)* custom);
        [id(5] HRESULT BeginShutdown([in] SAFEARRAY(VARIANT)* custom);
    };
    typdef enum
    {
        ext_cm_AfterStartup = 0,
        ext_cm_CommandLine,
        ext_cm_External,
        ext_cm_Startup,
    } ext_ConnectMode;
    typdef enum
    {
        ext_dm_HostShutdown = 0,
        ext_dm_UserClosed,
    } ext_DisconnectMode;

OnAddInsUpdate

Description

Changing the AddIn object's Connect property to True sets the add-in's connection flag from 0 to 1. This change triggers the OnAddInsUpdate event, which occurs whenever changes are made to any add-in listed in the Add-In Manager (or HKCU\Software\Microsoft\Office\9.0\<app>\AddIns subkey entries in the Windows Registry).

Using the Update method on the AddIns collection forces the Add-In Manager to re-read the list of add-in entries in the Registry. When this occurs, since the flag is now set to True, the add-in is connected.

For Visual Basic 6.0, the Addins collection is updated when it is accessed via DTE.Addins or when a user of the environment invokes the Add-In Registration Manager. OnAddinsUpdate fires if there are any changes.

Syntax

Sub object**_OnAddInsUpdate(**custom As Variant)

Value Description
custom An array of variant expressions to hold user-defined data.

Remarks

In Visual Basic 5, the equivalent method is executed automatically when changes are saved to the Vbaddin.ini file. Office does not use an *.ini file to determine the list of add-ins for an Office host application; rather it uses the Windows Registry to build a list of add-ins that are registered to be hosted in an Office application using the HKCU\Software\Microsoft\Office\9.0\<app>\AddIns subkey.

OnBeginShutdown

Description

Occurs just before the Office host application begins its unloading procedures.

Syntax

Sub *object_***OnBeginShutdown(**custom As Variant)

Value Description
custom An array of variant expressions to hold user-defined data.

Remarks

The OnBeginShutdown method enables scenarios where an add-in needs to save state information of any windows or dialog boxes before the Office host application unloads any UI or add-ins.

OnConnection

Description

Occurs when an add-in is connected to the Office host application, either through the Add-Ins dialog box or another add-in.

Syntax

Sub *object_*OnConnection(ByVal Application As Object, ByVal ConnectMode As ext_ConnectMode, ByVal AddInInst As Object, custom As Variant)

ValueDescription
ApplicationAn object representing the instance of the current Office host application session.
ConnectModeAn enumerated value of type ext_ConnectMode, as specified below.
 ConstantValueDescription
 ext_cm_AfterStatup0Add-In was started after any Office document loaded was shown.
 ext_cm_Startup1Add-In was started before any Office document is loaded in the Office host.
 ext_cm_External2Add-In was started externally by another program or component.
AddInInstAn AddInX object representing the instance of the add-in.
customAn array of variant expressions to hold user-defined data.

OnDisconnection

Description

Occurs when an add-in is disconnected from the Office host application.

Syntax

Sub *object_*OnDisconnection(ByVal Application As Object, ByVal RemoveMode As ext_DisconnectMode, custom As Variant)

ValueDescription
RemoveModeAn enumerated value of type DisconnectMode, as specified below.
 ConstantValueDescription
 ext_dm_HostShutdown0Add-In was removed by the add-in's host being closed.
 ext_dm_UserClosed1Add-in was removed by the user closing it
customAn array of variant expressions to hold user-defined data.

Remarks

The RemoveMode argument in the OnDisconnection is handy in scenarios where the add-in needs to determine whether to remove any command bar customizations it made when loaded. If an add-in is disconnected by the user, then the add-in should remove any menus and toolbars it added to the Office host application command bar set.

If the Office host application is disconnecting the add-in, the add-in should leave any customizations it made to the Office host command bar set so that the customizations are displayed the next time the Office host is launched. The add-in can then be demand-loaded during the next session of the Office host since its command bar customizations are already added. The add-in actually is loaded the first time the user clicks on a command bar customization.

OnStartupComplete

Description

Occurs when the startup of the Office host application is complete.

Syntax

Sub *object_***OnStartupComplete(**custom As Variant)

Value Description
custom An array of variant expressions to hold user-defined data.

Remarks

The OnStartupComplete method enables scenarios where an add-in needs to know when an Office host application has completed its startup sequences and loaded any files, add-ins, or other objects into memory. For example, when the OnStartupComplete method is executed, another add-in can then check if certain other add-ins were loaded or not during startup and, hence, determine the behavior of the add-in based on this information.

Add-In Object Model

The COM add-in object model can be accessed using the COMAddIns property on the Application object in Word, Excel, PowerPoint, Access, and any other Office family member application that chooses to use the COM add-in architecture from Office.

The COMAddIns property returns a COMAddIns collection that represents the COM add-ins in the Office application in which the COMAddIns property is accessed. The property is read-only. The COMAddIns collection object is defined in the Office object library. The ODL syntax for the COMAddIns accessor property in Word, Excel, PowerPoint, and Access is:

[propget] HRESULT COMAddIns([out, retval] COMAddIns **COMAddIns);

This functionality behaves the same as the CommandBars collection object. In each Office application, a CommandBars property is provided on the Application object. The CommandBars property returns a CommandBars collection that represents the menu bar and all the toolbars in Office application. The definition of the CommandBars collection and its members resides in the Office object library.

The naming convention used for the COMAddIns allows developers and documentation to make a clear distinction between native VBA add-ins from pre-Office 2000 (i.e., xla, ppa, dot, mda) and the new unified add-in architecture for Office 2000.

Even though the COM add-in object is COMAddIns and COMAddIn, the definition of the object in the Office object library is consistent with and contains a subset of the AddIns\AddIn object in Visual Basic 6.0 and Visual Studio 6.0.

Hierarchy

    Application
      |
      +---COMAddIns
         |
         +---COMAddIn
               |
               +---Application
               |
               +---Connect
               |
               +---Creator
               |
               +---Description
               |
               +---Guid
               |
               +---Object
               |
               +---Parent
               |
               +---ProgID

ODL Syntax

interface COMAddIns: _IMsoDispObj {
     [id(0)] HRESULT Item ([in] VARIANT *Index, [out, retval] COMAddIn **RetValue);
[id(1), propget] HRESULT Count ([out, retval] long *RetValue);
[id(0xfffffffc), propget, nonbrowsable, restricted] HRESULT _NewEnum ([out, retval] IUnknown **RetValue);
[id(2)] HRESULT Update ();
[id(3), propget] HRESULT Parent([out, retval] IDispatch **ppidisp);
};

   interface COMAddIn : _IMsoDispObj {
     [id(0), propget]HRESULT Description([out, retval] BSTR *Description);
     [id(1), propget]HRESULT Connect([out, retval] Boolean *Connect);
     [id(2), propput]HRESULT Connect([in] Boolean Connect);
     [id(3), propget]HRESULT Guid([out, retval] BSTR *Guid);
     [id(4), propget]HRESULT Parent([out, retval] IDispatch **Parent);
     [id(5), propget]HRESULT ProgID([out, retval] BSTR *ProgID);
     [id(6), propget]HRESULT Object([out, retval] IDispatch **Object);
   };

COMAddIns Collection Object

The COMAddIns collection object provides the normal collection object properties and methods: Count, Parent, and Item. The COMAddIns collection object also provides an Update method, which is consistent with the Visual Basic 5 AddIns object.

Properties

Application, Count, Creator, Parent

Methods

Item, Update

Application

Description

Returns the Application object of the host application from where the COMAddIns object was accessed.

Count

Description

Returns the number of add-ins registered for a particular Office application. Returns Long.

Creator

Description

Returns a 32-bit integer that indicates the application in which this object was created. For example, if the object was created in Microsoft Excel, this property returns the string XCEL, which is equivalent to the hexadecimal number 5843454C. Read-only Long.

Remarks

The Creator property is designed to be used in Microsoft Office for the Macintosh, where each application has a four-character creator code. For example, Microsoft Excel has the creator code XCEL. The Creator property works the same as every object in each application.

Item

Description

Returns a single member of the COMAddIns collection object. The index is a Variant because it can take an ordinal number that returns the element at that position in the collection or the string representing the ProgID of the COM add-in, which is a string. Returns the COMAddIn object.

Parent

Description

Returns the Application object of the Office host.

Update

Description

Refreshes the contents of the COMAddIns collection from the add-ins listed in the Windows Registry in the same manner as if the user had opened the Add-Ins dialog box.

Remarks

All add-ins listed in the Windows Registry must be registered COM components with corresponding Component Category IDs in the Registry before they can be used in an Office application.

COMAddIn Object

Description

The COMAddIn object provides information about an add-in to other add-ins. A COMAddIn object is created for every COM add-in that is registered in the Windows Registry.

Properties

Application, Connect, Creator, Description, Guid, Object, Parent, ProgID

Connect

Description

Returns or sets the connected state of an add-in. Read-write.

Remarks

Returns True if the add-in is registered and currently connected (active).

Returns False if the add-in is registered, but not connected (inactive).

Description

Description

Returns a string expression containing a descriptive string associated with an object. Read-only.

Guid

Description

Returns a String containing the class identifier of an object. Read-only.

Object

Description

Returns the object that is the basis for the COM add-in. Read-only.

Parent

Description

Returns the Application object of the Office host. Read-only.

ProgID

Description

Returns the ProgID (programmatic ID) for the add-in. Read-only.

CommandBar Customizations

In integrating COM add-ins with Office applications, Office 2000 hooks into the CommandBarItem click event internally only to parse the OnAction string before the host application receives the click event. If the syntax of the string is as specified for COM add-ins, Office 2000 will handle the event. Otherwise, the host application will deal with it.

The syntax for OnAction strings that targeted for COM add-ins is as follows:

!<ProgID>

To sink a CommandBarButton click, use the following Visual Basic 6-like syntax:

Implements IDTExtensibility2

Dim cbToolsMenu As Office.CommandBar
Dim cbAddInBtn As Office.CommandBarButton
Public WithEvents ButtonHandler As Office.CommandBarButton 'command bar event handler

Private Sub ButtonHandler_Click()
    MsgBox "ButtonHandler_Click"
End Sub

Private Sub IDTExtensibility2_OnConnection(ByVal Application As Object, _
    ByVal ConnectMode As ext_ConnectMode, _
    ByVal AddInInst As Object, custom() As Variant)

    Set cbToolsMenu = Application.CommandBars("Tools")
    Set cbAddInBtn = cbToolsMenu.Controls.Add(1)
    cbAddInBtn.Caption = "My &Office Add-In"

    'sink the event
    Set ButtonHandler = cbAddInBtn

End Sub

If Office does not find the ProgID recorded in the OnAction property, then the CommandBarItem click event will fall through to the next handler, which is located in the Office host application. The host will display any alerts, if they currently do, when the OnAction string does not match any valid macro names.

Note: ProgIDs cannot contain spaces.

ProgIDs are unique identifiers for COM add-ins, whereas a file name would not necessarily be unique in terms of specifying which Class in a COM add-in the developer wants to invoke. A COM add-in can have more than one Class, and hence, more than one add-in, implemented in any one file.

If the OnAction string contains a ProgID, it is converted to a CLSID, and Office iterates through the Windows Registry to find the associated, registered COM add-in. If the add-in is a native VBA add-in for Word, Excel, PowerPoint, and Access, you do not have to provide the ProgID and can use the current OnAction string syntax supported by the Office application.

CommandBarButton Click Event

Office 2000 supports the Click event on the CommandBarButton object. To provide more functionality and make more scenarios available to the COM add-in developer, the definition for the Click event procedure is passed the CommandBarButton object that triggered the click event. To be similar to Visual Basic, the CancelDefault argument is also passed.

Syntax

Sub object_Click (ByVal Ctrl As CommandBarButton, ByRef Handled As Boolean, ByRef CancelDefault As Boolean)

The Click event syntax has these named arguments:

Argument Description
Ctrl Required. Object. Specifies the object that is the source of the Clickevent.
CancelDefault Required. Boolean. If True, the default behavior of the CommandBarButtoncontrol is not performed unless restored by a downstream add-in. If False, the default behavior is performed unless canceled by a downstream add-in.

Remarks

The Click event is specific to the CommandBarButton object. Use a variable declared using the WithEvents keyword to receive the Click event for a CommandBarButton control. This variable should be set to the CommandBarButton object. When the CommandBarButton control is clicked (for the variable you declared using the WithEvents keyword), the code is executed.

With regards to the Handled argument used in the similar Click event in Visual Basic 5: The 'Handled' parameter is inconsistent with all other events that are fired by both Visual Basic IDE and Office Applications. No other event, other than Visual Basic's CommandBarEvents::Click, has a 'Handled' parameter. The 'Handled' parameter cannot have any consistent results in its use. The order that events will be multi-cast is completely arbitrary. Adding the 'Handled' parameter to the Click event will result in specialized code within the generic event code of Office.

CommandBarComboBox Change Event

Office 2000 supports the Change event on the CommandBarComboBox object. To provide more functionality and make more scenarios available to the COM add-in developer, the definition for the Change event procedure is passed the CommandBarComboBox object that triggered the change event. The Change event should fire with the exact same behavior as the OnAction property of the CommandBarComboBox object. The OnAction property internally was set to fire on the change event in Office 97 and in Office 2000.

Syntax

Sub object_Change (ByVal Ctrl As CommandBarComboBox)

The Click event syntax has the following named argument:

Value Description
ctrl Required; Object. Specifies the object that is the source of the Change event.

CommandBars OnUpdate Event

Office 2000 supports the OnUpdate event on the CommandBars object. The OnUpdate event is fired when a change to any command bar has occurred.

Syntax

Sub object_OnUpdate ()

Value Description
object_ Specifies the object that is the source of the OnUpdate event

CommandBars.FindControls Method

In the current implementation of the CommandBars.FindControl method, if the CommandBars collection contains two or more controls that fit the search criteria, FindControl returns the first control that's found.

With the new CommandBars.FindControls method, if the CommandBars collection contains two or more controls that fit the search criteria, FindControls returns a CommandBarControls collection containing the found controls.

As with the FindControl method, if no control that fits the criteria is found, FindControls returns Nothing. The rest of the definition, syntax, and description for the FindControls method are the same as the current FindControl method. Note, too, that the parent of a control in the CommandBarControls collection returned from the FindControls method is the natural parent of the control and not the CommandBars collection. This is the same for something like: Application.CommandBars.FindControl(id:=287).Parent.Name

interface _CommandBars: _IMsoDispObj
{
    // New method exactly the same as FindControl but returns 
    // a controls collection from the search rather than the
    // first control found.
    HRESULT FindControls([optional, in] VARIANT Type,
        [optional, in] VARIANT Id,
        [optional, in] VARIANT Tag,
        [optional, in] VARIANT Visible,
        [out, retval] CommandBarControls **ppcbcs);
}

OnAction Syntax for Office 97 Applications

Both PowerPoint and Excel 97 support the following syntax in the OnAction property for a CommandBarControl object. This code shows a sample that works for Excel and PowerPoint.

<file name>!<module name>.<macro name>

The file name string is separated by a bang operator, and the module name and macro name strings are separated by a period.

When this syntax is used in Word 97, code execution fails on the attempt to assign the OnAction string. Word parses the string and determines if it is a valid macro name. Access 97 allows you to assign the OnAction string with the syntax above. However, it does not support the parse the OnAction and alerts when it cannot find a macro with the specified OnAction string in the current database.

When Word's Normal.dot file is locked or read-only, a user cannot save command bar customizations that appear in Word on a global scale. Command bar customizations that need to appear for all sessions of Word and need to be provided for any open document must appear in global templates that are loaded in an instance of Word. However, as more and more companies lock down Normal.dot and other global templates to prevent the spread of viruses, Word no longer provides a mechanism for storing global command bar customizations.

To solve the issue for allowing OnAction strings with the syntax targeted for COM add-ins, Word must allow OnAction strings to be stored with the COM add-ins syntax. In addition, Word should provide the same mechanism as Excel, PowerPoint, and Access in order to persist command bar customizations that do not have a context, thus allowing the same consistent implementation of command bar customizations for an COM add-in.

Sub AddMenuItem()
    Dim oCmdCtl As CommandBarControl
    'Application.CustomizationContext = NormalTemplate
   With CommandBars("Menu Bar").Controls("Help").Controls
        Set oCmdCtl = .Add(msoControlButton, , , 1)
        With oCmdCtl
            .Caption = "MyMenuItem"
         .OnAction = "C:\Temp\MyFile.xls!MyModule.MyMacro"
        End With
    End With
End Sub

Sub MyMacro()
    MsgBox "MyMacro in module MyModule."
End Sub

Storing Command Bar Settings

The custom command bars and the settings for which command bars are visible are stored by the application, and then used the next time you run the application. The storage location varies with the application.

Microsoft Excel

Command bar settings are stored in the Windows folder in a file named <username>.xlb. If you delete this file, you will lose all of your custom command bars. The next time you start Microsoft Excel, the default command bars will be visible.

In Microsoft Excel, you can attach a command bar to a workbook. If you give the workbook to another user, the command bar will be included. When the workbook is opened, the command bar will be copied to the user's system in the <username>.xlb file. If a command bar with the same name already exists in that file, the command bar will not be copied.

Microsoft Word

Command bars are stored with a template or document. When you create a new command bar, you can specify where you want to store it. If you want a command bar to be available to all Word documents, you can store it in the Normal.dot template or a global template.

Microsoft Access

Changes to built-in toolbars are stored globally and will be applied each time you start Microsoft Access. Custom command bars are stored in a specific database.

Microsoft PowerPoint

Custom command bars are stored in the Windows directory in the <username>.pcb file. The next time you start PowerPoint, the default command bars will be visible. If you delete this file, you will lose your custom command bars.

Displaying Images for COM Add-In Command Bar Customizations

COM add-ins cannot attach custom command bars with button images as Excel, Access, and Word 97 currently provide. However, you can create command bars from code within the COM add-ins, load images stored in a resource file to the Clipboard, and use the PasteFace method of the CommandBarControl object to display the button image.

Add-In Registration

Initially, when loading, previous versions of Office looked through the class ids for any item registered with a certain cat id. However, this hindered boot performance. Office now stores the list of registered and connected add-ins in a subkey under the Office root. Office now uses the registry strictly to list all add-ins in the COM add-ins collection and uses the registry to store connected/disconnected state as well as boot or demand loaded information.

In this new mechanism, the name of the add-in is stored under the key: HKCU\Software\Microsoft\Office\9.0\<app>\AddIns where <app> will be: Word, Excel, PowerPoint, Access, and Outlook. The Add-In Designer comes in handy for developers, so you can specify under which Office application subkey the add-in should register itself. See below for more details on the Add-In Designer registration.

This method makes the Office shared add-in code easier because it does not have to know which application it is working on behalf of.

PowerPoint currently writes an \AddIns\ subkey in Office setup under HKCU. Each subkey under \AddIns\ is the name of a native VBA add-in. However, this design does not conflict with Office's design since Office only iterates the values under the \AddIns\ subkey and does not read subkeys.

Office Add-In Registry Structure

HKCU/Software/Microsoft/Office/
    /<app>/AddIns/
        ProgID1
        ProgID2
            :

For each add-in ProgID listed, the following name/value pairs exist:

FriendlyName The name that appears in the COM Add-Ins dialog box.
LoadBehavior DWORD bit field with the LoadBehavior flag set. See below for flag values.
FileName The name that appears in the group box at the bottom of the COM Add-Ins dialog box. This string is also used for Roaming User scenarios. See Description under the Roaming Users heading below.

Visual Studio 6.0 Registration (for comparison)

Visual Studio 6.0 looks to the registry to find add-ins:

HKCU/Software/Microsoft/VisualStudio/
    6.0/AddIns/
        ProgID1
        ProgID2
    7.0/AddIns/
        ProgID3
        ProgID4
HKCU/Software/Microsoft/VisualBasic/
    5.0/
:
    6.0/

For each add-in ProgID listed, the following name/value pairs exist:

FriendlyName The name that appears in the Add-In Manager dialog box
Description A string to display at the bottom of the Add-In Manager dialog box when the add-in is selected
LoadBehavior DWORD bit field with the following bits (for Visual Basic, VBE, VSE, Visual Studio )
SatelliteDllPath  
SatelliteDllName  

Add-In Designer Registration

The Add-In Designer, included with Visual Basic 6.0, Visual Studio 6.0, and Office 2000 Developer (it is not included in the Standard or Pro versions of Office), will registry itself under: HKEY_LOCAL_MACHINE\Software\Microsoft\Shared Tools\Addin Designer.

Each application thereafter registered on the machine registers an Application Name key under the Addin Designer. The value under the Application Name key is used in the UI of the Add-in Designer in Visual Basic 6.0. When a designer is added to a Visual Basic 6.0 project, the user selects which application the add-in should be registered for and what the load behavior is. If the add-in works for multiple applications, more than one designer instance is added to the Visual Basic project, and each designer project item is set to a specific application.

HKEY_LOCAL_MACHINE\Software\Microsoft\Shared Tools\Addin Designer
    \"Application Name"
        \"Application Version" = "Application's Add-In registry location"
            \LoadBehaviors = 
                                    LB_1= (DWORD)
                                    LB_2= (DWORD)
                                          :
                                    LB_x= (DWORD)
            \Options = CommandLine = 1 (optional)

Office LoadBehavior Flags — Registry Values

For performance reasons, the possible states of the add-in and load information are combined in a DWORD rather than creating a subkey for each add-in and adding individual values for each state information. It is slower to iterate through subkeys than it is to iterate through values.

DWORDs for value data stored in the Registry for each add-in name:

Disconnected 0
Connected 1
BootLoad 2
DemandLoad 8
ConnectFirstTime 16

If ConnectFirstTime is set, the Connected flag is ignored. Once the add-in is loaded, the ConnectFirstTime flag is cleared and the Connected flag is set.

Order of connect flag consideration: ConnectFirstTime >> Connected.

When a COM add-in is loaded:

  BootLoad DemandLoad
Connected Boot Button Click
Disconnected Never Never

When Office disconnects an unregistered add-in, the add-in entry is removed from the \AddIns\ subkey in the Registry.

Visual Studio 6.0 LoadBahvior Flags (for comparison)

ID_UNLOADED = 0
ID_LOADED = 1 //Only used to note a default when the add-in is first seen by the Add-In Manager
ID_STARTUP = 2
ID_COMMAND_LINE = 4
CommandLineSafe [OPTIONAL] - indicates whether the add-in author thinks 
      the add-in is safe to load when the environment is started 
      from the command line (that is, the add-in was coded to avoid 
      UI in this situation).

Note: Modifying the Microsoft Windows registry in any manner, whether through the Registry Editor or programmatically, always carries some degree of risk. Incorrect modification can cause serious problems that may require you to reinstall your operating system. It is a good practice to always back up a computer's registry first before modifying it. If you are running Microsoft Windows NT or Microsoft Windows 2000, you should also update your Emergency Repair Disk (ERD). For information about how to edit the registry, view the "Changing Keys and Values" Help topic in the Registry Editor (Regedit.exe) or the "Add and Delete Information in the Registry" and "Edit Registry Information" topics in the Registry Editor (Regedt32.exe).

Debugging

Debugging tools are included with Visual Basic 6.0, Visual C++, and Visual J++. Cross-process currently works with Visual Basic 5.0 COM DLLs referenced in a Microsoft Office 97 VBA project.

In Office 2000, to debug a project in Visual Basic, for example, you would put the project in Run mode in Visual Basic. Visual Basic then takes care of registering the project as the active registered server.

Then you switch to an Office host application and from the Add-Ins dialog box, check the COM add-in in the Add-Ins available list box, and click OK.

Office then connects to the COM add-in, allowing you to set breakpoints and step through code in the COM add-in in the Visual Basic development environment.

Worldwide, Localization, East Asia

Using Visual Basic 5+ or 6.0 to develop custom add-ins for Office allows you to take advantage of the resource functionality of Visual Basic. Visual Basic 4.0 and 5+ allows you to import a Resource file (.RES) into your projects. When the project is compiled, the resources are compiled into standard Windows Resources, which can be manipulated and loaded into any current resource editor, like Visual C++ 4.x and Espresso 2.0.

Using the resource methods LoadResString, LoadResData, and LoadResPicture provided by Visual Basic 5+, you can create localizable and international solutions for Office 2000.