Implementing IDTExtensibility2
The key to understanding COM add-in development is the IDTExensibility2 interface. This interface is used by all Office applications to communicate with a COM add-in. This ensures a common initialization mechanism and an ability to pass in the application's object model so that the COM add-in can communicate with the Office application. Listing 23-1 shows the IDTExtensibility2 interface.
Listing 23-1. The IDTExtensibility2 Interface
public interface IDTExtensibility2 { void OnAddInsUpdate(ref System.Array custom); void OnBeginShutdown(ref System.Array custom); void OnConnection(object Application, Extensibility.ext_ConnectMode ConnectMode, object AddInInst, ref System.Array custom); void OnDisconnection(Extensibility.ext_DisconnectMode RemoveMode, ref System.Array custom); void OnStartupComplete(ref System.Array custom); }
Startup Order
IDTExtensibility2 is a simple interface, but it is important to note the loading order of the COM add-in and how that impacts where you write your code. Office instantiates your COM add-in, which causes your main Connect class to be created. But there is a key difference to normal programming practice in that the constructor of your Connect class cannot really be used to set up your class because the Office application context (typically the Application object from the Office application's object model) is not made available in the constructor. Instead, it is provided via the OnConnection method on the IDTExtensibility2 interface. Likewise, the shutdown behavior for an add-in is determined not by the destructor of the class but by when the OnDisconnection method is called.
Figure 23-5 illustrates the order in which these events occur for a COM add-in. First the COM add-in is loaded and the Connect class is created. This results in the Connect class's constructor being called. Then the Connect class's implementation of IDTExtensibility2.OnConnection is called, and the Office application's Application object is passed via this method. The Connect class's implementation of IDTExtensibility2.OnStartupComplete is called. The add-in is now loaded and connected Then, when the application exits or the user unloads the add-in, the Connect class's implementation of IDTExtensibility2.OnBeginShutdown is called followed by a call to IDTExtensibilty2.OnDisconnection.
Figure 23-5. Order of COM add-in startup and shutdown.
The OnAddInsUpdate Method
The OnAddInsUpdate method is called when any COM add-in is loaded or unloaded in the Office application. This method is somewhat of an anomaly because the contents of the custom argument are never set by Office applications. As a result, this method can only really be used to tell you that a COM add-in has been loaded or unloaded, and you can then query the COMAddins collection in the application object model to see what has been loaded or unloaded. A good example of using this method is if your COM add-in relies on other COM add-ins to be running in order to work properly; so if one of the dependent COM add-ins is unloaded, your COM add-in can unload:
void OnAddInsUpdate(ref System.Array custom);
Parameter |
Description |
---|---|
custom |
An array of object that the host application can use to provide additional data. None of the Office applications set this value. |
The OnBeginShutdown Method
The OnBeginShutdown method is called on a connected COM add-in when the Office application is being shut down:
void OnBeginShutdown(ref System.Array custom);
Parameter |
Description |
---|---|
custom |
An array of object that the host application can use to provide additional data. None of the Office applications set this value. |
The OnConnection Method
The OnConnection method is called when a COM add-in is loaded into the environment. This method is the main entry point for the COM add-in because it provides the Application object from the Office application's object model that the add-in will use to communicate with the Office application:
void OnConnection(object Application, Extensibility.ext_ConnectMode ConnectMode, object AddInInst, ref System.Array custom)
Parameter |
Description |
||
---|---|---|---|
Application |
The application object of the Office application passed as an object. Because IDTExtensibility2 is a general-purpose interface, this has to be an object rather than a strongly typed parameter. This object can be cast to the Application object type of the Office application. |
||
ConnectMode |
The ext_ConnectMode constant specifying how the COM add-in was loaded. There are six possible values: |
||
Constant |
Value |
Description |
|
ext_cm_AfterStartup |
0 |
COM add-in was loaded after the application started. Typically this is if user has chosen to load an add-in from the COM Add-Ins dialog. |
|
ext_cm_Startup |
1 |
COM add-in was loaded at startup. |
|
ext_cm_External |
2 |
COM add-in was loaded externally by another program or component. |
|
ext_cm_CommandLine |
3 |
COM add-in was loaded through the application's command line. |
|
ext_cm_Solution |
4 |
COM add-in was loaded when user loaded a solution that required it. |
|
ext_cm_UISetup |
5 |
COM add-in was started for the first time since being installed. |
|
AddInInst |
An object representing the COM add-in. This can be cast to a COMAddIn object from the office.dll PIA in the Microsoft.Office.Core namespace. |
||
custom |
An array of object that the host application can use to provide additional data. None of the Office applications set this value. |
The OnDisconnection Method
The OnDisconnection method is called when a COM add-in is unloaded from the application either because the application is shutting down or because the user disabled the COM add-in using the COM Add-Ins dialog:
void OnDisconnection(Extensibility.ext_DisconnectMode RemoveMode, ref System.Array custom);
Parameter |
Description |
||
---|---|---|---|
RemoveMode |
The ext_DisconnectMode constant specifies why the COM add-in was unloaded. |
||
Constant |
Value |
Description |
|
ext_dm_HostShutdown |
0 |
COM add-in was unloaded when the host application was closed. |
|
ext_dm_UserClosed |
1 |
COM add-in was unloaded when the user cleared its check box in the COM Add-Ins dialog box, or when the Connect property of the COMAddIn object corresponding to the COM add-in was set to false. |
|
ext_dm_UISetupComplete |
2 |
COM add-in was unloaded after the environment setup completed and after the OnConnection method returns. |
|
ext_dm_SolutionClosed |
3 |
Only used with Visual Studio COM add-ins |
|
custom |
An array of object that the host application can use to provide additional data. None of the Office applications set this value. |
The OnStartupComplete Method
The OnStartupComplete method is called when the Office application has completed starting up and has loaded all the COM add-ins that were registered to load on startup:
void OnStartupComplete(ref System.Array custom);
Parameter |
Description |
---|---|
custom |
An array of object that the host application can use to provide additional data. None of the Office applications set this value. |
A Simple Implementation of IDTExtensibility2
Listing 23-2 shows a simple implementation of IDTExtensibility2 similar to what is generated when you create an add-in project in Visual Studio. This implementation displays several message boxes to give you information about the methods of IDTExtensibility2 that are being called on the Connect class. It is a COM add-in that loads into Excel, so it casts the application object to the Microsoft.Office.Interop.Excel. Application type. It also casts the addInInst object to the Microsoft.Office.Core. COMAddin type. Note also that the InteropServices namespace is used to add a GuidAttribute and ProgID attribute. The values of these attributes are used when registering the add-in, as described earlier in the chapter.
Listing 23-2. An Excel COM Add-In Connect Class That Implements IDTExtensibility2
namespace MyAddin1 { using System; using Extensibility; using System.Runtime.InteropServices; using System.Windows.Forms; using Excel = Microsoft.Office.Interop.Excel; using Office = Microsoft.Office.Core; [GuidAttribute("649D6562-F01F-4117-BF2C-198CDD3E11E4"), ProgId("MyAddin1.Connect")] public class Connect : Object, Extensibility.IDTExtensibility2 { public Connect() { MessageBox.Show("Connect Constructor"); } public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom) { MessageBox.Show("OnConnection"); Office.COMAddIn addin = addInInst as Office.COMAddIn; MessageBox.Show("My add-in ProgID is " + addin.ProgId); Excel.Application app = application as Excel.Application; MessageBox.Show(String.Format( "The application this loaded into is called {0}.", app.Name)); MessageBox.Show(String.Format( "Load mode was {0}.", connectMode.ToString())); } public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode, ref System.Array custom) { MessageBox.Show("OnDisconnection"); MessageBox.Show(String.Format( "Disconnect mode was {0}.", disconnectMode.ToString())); } public void OnAddInsUpdate(ref System.Array custom) { MessageBox.Show("OnAddinsUpdate"); } public void OnStartupComplete(ref System.Array custom) { MessageBox.Show("OnStartupComplete"); } public void OnBeginShutdown(ref System.Array custom) { MessageBox.Show("OnBeginShutdown"); } }