Programming Microsoft Outlook and Microsoft Exchange, Second Edition (DV-MPS Programming)

When developing Office solutions, you probably want to extend existing Office applications—Outlook in this case—with new functionality. With Outlook 98, you could add new forms to your application's Outlook environment, but you could not easily add new toolbars or program your application to respond to events beyond the form events, such as Item_Open or Item_Read. Plus, if you really wanted to extend beyond forms, you had to write an Exchange Client Extension. Exchange Client Extension development involved strict requirements and coding practices, and any extensions had to be written using C/C++. This meant that as a Microsoft Visual Basic or VBA developer, you were stuck either hacking a solution together or not enhancing the functionality at all.

Office 2000 includes support for COM add-ins. A COM add-in is a dynamic-link library (.dll) that can be used in an Office 2000 application. COM add-ins are used to include additional functionality in an Office application. As you can guess by the name, COM add-ins can be built using any COM development tool, such as Visual Basic, Microsoft Visual C++, or even Microsoft Visual J++. Since COM add-ins are compatible with all Office products, you can design a COM add-in once and reuse it in another Office product. For example, you could write a COM add-in that customizes the toolbars in your applications by using the CommandBar object model, which is shared across all of the Office products.

In this chapter, we'll look at a COM add-in that cannot be used across all the Office applications since it does call specific Outlook functionality. However, the concepts required to build this COM add-in can be applied to any add-in designed for other Office applications.

COM add-ins are registered specifically to be loaded by Office 2000 applications. Since COM add-ins are designed as DLLs, they will run in the same process as the host application. One benefit of an in-process add-in is that it has efficient access to the object model of the host application, allowing the add-in to quickly call methods and properties or to receive events from the host application. One potential caution to running an add-in in the same process space as the host is that you're in danger of slowing down or even crashing the host application. Keep this in mind during development.

Deciding Whether to Write a COM Add-In

You need to consider a number of issues when deciding whether to develop a COM add-in. Some of the functionality COM add-ins provide in Outlook is similar to other Microsoft Exchange and Outlook development technologies, such as the Event Scripting Agent, which we'll discuss in Chapter 12. For this reason, I've provided three test questions to help you determine whether to create a COM add-in or use another technology.

First, do you need to receive events when the Outlook client is not running? The life span of your COM add-in is controlled by Outlook. When the Outlook process is running, your COM add-in can run and receive events. When Outlook is not running, your add-in is also not running. If you need to receive events when the Outlook client is not running, you might want to consider using the Event Scripting Agent; because your agent runs on the server, it will always receive events while the server is running. In the next chapter, we'll examine a COM add-in that notifies users when an item in a folder changes—functionality that might be better implemented by using the Event Scripting Agent.

The second test question to answer is this: is performance a big concern for your application? If so, you should use an add-in because it is loaded in-process with Outlook, but be aware that you must use defensive coding practices to prevent crashing Outlook. Don't create an add-in that performs expensive lookups or data retrievals when starting, because Outlook will wait for it to finish before continuing.

Third, is your application event-driven? Outlook will fire a number of new events that your COM add-in can implement and handle. These new events allow you greater control over the Outlook user interface and Outlook data.

Developing a COM Add-In

If your application passes my three test questions, start developing your COM add-in! It is actually quite easy as Visual Basic has some features that can get you up and developing in a matter of minutes. In this section, we'll take a look at how to start developing COM add-ins, and then we'll review the new features of the Outlook Object Model that you can employ in your COM add-ins.

Before you can begin creating an add-in, you must start Visual Basic 5.0 or a later version and select an ActiveX DLL project. After the new project loads, you must select Microsoft Add-In Designer from the Project/References dialog box, as shown in Figure 9-1. This type library contains the necessary interfaces for your COM add-ins.

Figure 9-1 Select the Microsoft Add-In Designer from the Project/References dialog box.

In your Visual Basic code, you will need to type Implements IDTExtensibility2 to see the IDTExtensibility2 interface's events in the Procedure drop-down list in the Visual Basic code window. Figure 9-2 shows the code window with all of the IDTExtensibility2 event procedures added.

Figure 9-2 The Visual Basic 6.0 code window with the five event procedures for the IDTExtensibility2 interface.

The IDTExtensibility2 Events

As you can see in Figure 9-2, IDTExtensibility2 provides five events for you to use in your COM add-in: OnConnection, OnDisconnection, OnStartupComplete, OnBeginShutdown, and OnAddInsUpdate. Let's examine each of these events.

OnConnection event The OnConnection event is called when your add-in is first loaded or connected to—for example, when Outlook starts, or when the user selects to load your COM add-in. The user can select your add-in in the COM Add-Ins dialog box in Outlook 2000. You can access this dialog box in Outlook by choosing Options from the Tools menu, selecting the Other tab, clicking Advanced Options, and clicking COM Add-Ins. This dialog box is shown in Figure 9-3.

Figure 9-3 The COM Add-Ins dialog box in Outlook 2000, where users can add or remove COM add-ins. Using the Registry, you can force your add-ins to always load no matter what the user selects.

The OnConnection event procedure is a great place to grab and store the Outlook Application object for use in your code later. When an OnConnection event occurs, the OnConnection event procedure is passed the following four parameters: Application, ConnectMode, AddInInst, and Custom(). The Application parameter is a reference to the Outlook Application object. The ConnectMode parameter describes the way in which the COM add-in was loaded. The ConnectMode parameter is a Long data type that can be set to one of the following constants: ext_cm_AfterStartup, ext_cm_CommandLine, ext_cm_External, or ext_cm_Startup. The constants ext_cm_CommandLine and ext_cm_External do not apply to Office 2000 add-ins. The ext_cm_AfterStartup and ext_cm_Startup constants are subtly different from each other. The ConnectMode parameter is set to ext_cm_AfterStartup when the add-in is connected after Outlook starts or when the Connect property of the add-in is set to True. Usually, the ConnectMode parameter is set to ext_cm_AfterStartup when the user connects the add-in manually through the user interface. The ConnectMode parameter is set to ext_cm_Startup when your add-in is connected at the time Outlook starts up. The AddInInst parameter passes an object that refers to the current instance of your COM add-in. The Custom() parameter is an array of Variant data types that can hold user-defined data for your add-in. For Office 2000 add-ins, this parameter should be ignored.

OnDisconnection event The OnDisconnection event occurs when your COM add-in is being disconnected from the application. The OnDisconnection event procedure is passed two parameters: RemoveMode and Custom(). The RemoveMode parameter, which is a Long data type, specifies how your add-in was disconnected and can be set to these constants: ext_dm_HostShutdown or ext_dm_UserClosed. As you can guess by their names, ext_dm_HostShutdown indicates that the add-in is disconnected by the host shutting down, and ext_dm_UserClosed indicates either that a user is unchecking the add-in's check box in the COM Add-Ins dialog box or that the Connect property of the add-in is set to False.

The second parameter, Custom(), is an array of Variant data types that can hold user-defined data for your add-in. For Office 2000 add-ins, this parameter should be ignored.

Use the OnDisconnection event to restore any changes made to the application or to perform general cleanup for your application. Make sure you destroy any inspectors or explorers that you create since Outlook will not properly close if any of these objects still exist.

OnStartupComplete event In the case where a COM add-in connects at the time the host application is started, the OnStartupComplete event fires when the host has completed all of its startup routines. The OnStartupComplete event will not occur when a user selects to load the add-in from the COM Add-Ins dialog box after the application has already loaded. In that case, the OnConnection event will fire. The OnStartupComplete event procedure takes one parameter, Custom(), which you should ignore.

In this event procedure, place code that interacts with the application and should not be run until the application finishes loading. This event procedure is a good place to set some of your local and global variables to their corresponding Outlook objects. In the COM add-in example for Chapter 10, the OnStartupComplete event procedure searches the Outlook groups for a shortcut to the Account Tracking application and also has code to manipulate the command bars in the user interface.

OnBeginShutdown event The OnBeginShutdown event is fired when the application is about to shut down and is called before the OnDisconnection event. Even after the OnBeginShutdown event fires, you still have full access to the Outlook object model, so you can save your settings to the Registry or a file, or save any changes to your objects, before your objects are unloaded.

NOTE


If you are using Explorer objects in your COM add-in, listen for the Close event on your Explorer objects. When your application receives this event, it should destroy all your open Explorer objects because your Outlook COM add-in will not correctly shut down if any Explorer objects are left open.

OnAddInsUpdate event The OnAddInsUpdate event is fired whenever the list of COM add-ins is updated. When another add-in is connected or disconnected, this event occurs in any other connected COM add-in. You can use this event to ensure that any other add-in upon which your add-in is dependent is connected. Once the dependent add-in is disconnected, you can disable your functionality or display a dialog box to warn the user to reconnect the other add-in. The OnAddInsUpdate event handler includes one parameter, Custom(), which your application should ignore.

Registry Settings for COM Add-Ins

Now that you know which events fire for add-ins, you need to know how to register and load the add-ins. Outlook decides which add-ins to load based on settings in the user's Registry. If your add-in is not specified correctly in the Registry, Outlook will not be able to load your add-in nor will your add-in appear in the COM Add-Ins dialog box.

Registering your add-in For your add-in to work correctly, you must first compile and register the DLL that the add-in is based on. To do this, use the Regsvr32 command and specify the path to your DLL. This will register your DLL under the HKEY_CLASSES_ROOT subtree in the Registry. If you are deploying your add-in to multiple machines, you will have to figure out how to install your DLL file on those machines. One way would be to use logon scripts to copy and register the DLL. Another way would be to deploy your add-in using either the Visual Basic deployment and setup tools or Microsoft Systems Management Server (SMS).

Once your COM add-in DLL is registered, you need to add some additional settings into the Registry on the local machine. These settings include the add-in's name, description, target application, initial load behavior, and connection state.

Before writing this information to the Registry, you must first decide how you want to deploy your add-in: you can either force all users to use your add-in or allow each user to decide whether he or she wants to load the add-in. The model you select determines where in the Registry the information for your add-in has to be written. If you want to ensure the add-in is always loaded and that every user on a machine has access to it, you must register it under the key \HKLM\Software\Microsoft\Office\<application> \AddIns and lock down the Registry because the COM Add-Ins dialog box cannot unload add-ins registered there. If you want to give your users the option to specify whether they want the add-in loaded and to choose their own settings for the add-in, install your add-in under this key:

\HKCU\Software\Microsoft\Office\<application>\AddIns

This location allows per-user settings for the add-in. An example of registering your add-in under this key is shown in Figure 9-4.

Figure 9-4 This Registry shows an add-in loaded under the key \HKCU\Software\Microsoft\Office\Outlook\AddIns. Registering your add-ins under this key will allow per-user settings.

When you register your add-in under one of these Registry keys, the information written to the key includes the following name/value pairs: Description, FriendlyName, and LoadBehavior. Description is a string type that provides a short description of the COM add-in. FriendlyName is a string type that is the name displayed in the COM Add-Ins dialog box. LoadBehavior is a DWORD type where the value is an integer that specifies how to load your COM add-in. This integer can have a value of 0 for Disconnected, 1 for Connected, 2 for load on startup, 8 for load on demand, or 16 for connect first time. You can combine these values to create different types of load sequences. For example, if you assign the value 3 to your LoadBehavior, the add-in will be loaded on startup as well as connected. If you assign 9 to the add-in, the add-in will be connected and loaded when necessary, such as when the user clicks a button that uses code in the add-in.

The following code shows the content of a sample Registry editor file (.reg) for a COM add-in:

REGEDIT4 [HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook\ Addins\Sample.MyAddIn] "FriendlyName"="My Sample Add-In" "Description"="Sample Outlook COM Add-In" "LoadBehavior"=dword:00000003

Trusting your COM add-ins You can specify whether to trust all installed COM add-ins on a machine by setting the DWORD value DontTrustInstalledFiles under the following Registry key:

\HKCU\Software\Microsoft\Office\9.0\Outlook\Security

By assigning 0 to DontTrustInstalledFiles, you are specifying that Outlook trust all installed add-ins. A value of 1 specifies to not trust all add-ins.

Debugging Your COM Add-In

Debugging your add-in using Visual Basic 6.0 is easy. All you need to do is write your add-in, register it, set some breakpoints on the code statements you are interested in, and then run the add-in in the Visual Basic 6.0 environment. In the Project Properties dialog box, shown in Figure 9-5, you can set some debugging options. You can specify whether you want to wait for the component to be created by the host application or you want Visual Basic to start an instance of the host application for you. Most times, I specify to wait for the components to be created by the host application. After Outlook starts and creates the COM add-in, the code in the add-in will execute and stop on encountered breakpoints. You can then step through your code in the Visual Basic Editor.

Figure 9-5 The Debugging tab of the Project Properties dialog box in Visual Basic version 6.0. You can specify how you want Visual Basic to debug your ActiveX DLL.

When debugging, be aware that message boxes in your add-in will appear in the Visual Basic development environment, not Outlook. If Outlook stops responding, you should switch to Visual Basic to see if a message box is visible and waiting for you to respond.

Категории