Make Outlook addin / plug-in in Delphi.
Add a custom ribbon tab, region, menu.

Add-in Express™
for Microsoft® Office and Delphi® VCL

Add-in Express Home > Add-in Express for Office and Delphi VCL > Online Guide > Building Outlook plugins in Delphi

Building Outlook add-ins in Delphi

Add-in Express allows building COM add-ins for Microsoft Outlook 2021- 2003 with a single code base. It provides the Outlook-specific add-in module and two Outlook-specific command bar components: TadxOlExplorerCommandBar and TadxOlInspectorCommandBar. The former adds a command bar to the Outlook Explorer window and solves many problems with custom Outlook command bars. The latter adds a command bar to the Outlook Inspector window. Both command bar components have the FolderName, FolderNames and ItemTypes properties that add context-sensitivity to Outlook command bars. The olExplorerItemTypes, olInspectorItemTypes, and olItemTypeAction properties add context-sensitivity to Outlook command bar controls.

Additionally, the Add-in Express Outlook Add-in wizard allows creating property pages which will be shown in the Options (Tools | Options menu) and folder Properties dialogs.

The sample project described below implements a COM add-in for Outlook. See also How to create an add-in for Excel, Word and PowerPoint.

Step 1. Build an Outlook COM add-in project

Make sure that you have administrative permissions and run Delphi via the Run as Administrator command.

To build an Outlook COM add-in project in the Delphi IDE, use the Outlook Add-in project template available in the New Items dialog:

Create a new Outlook COM add-in project

When you select the Outlook add-in template and click OK, the project wizard starts. In the wizard windows, you choose the project options, define task panes and option pages for your Outlook plugin.

Outlook COM add-in wizard

Adding property pages to Outlook folders

The wizard builds and opens a new Outlook COM add-in project in the Delphi IDE.

The structure of the Outlook add-in project

The add-in project includes the following items:

  • Project source files (ProjectName.*)
  • Type library files (ProjectName_TLB.pas)
  • Outlook add-in module (ProjectName_IMPL.pas and ProjectName_IMPL.dfm) discussed in the following step
  • Outlook Property Page (PropertPage1.pas and PropertPage1.dfm) discussed in Step 12. Adding Property Pages to the Folder Properties Dialogs

Step 2. COM Add-in module

The add-in module (MyOutlookAddin1_IMPL.pas and MyOutlookAddin1_IMPL.dfm) is the core part of the COM add-in project. It is a container for Add-in Express components. You specify the add-in properties in the module's properties, add the required components to the module's designer, and write the functional code of your add-in in this module.

The code for MyAddin1_IMPL.pas is as follows:


unit MyOutlookAddin1_IMPL;

interface

uses
  SysUtils, ComObj, ComServ, ActiveX, Variants, Office2000,
  adxAddIn, MyOutlookAddin1_TLB, Outlook2000;

type
  TcoMyOutlookAddin1 = class(TadxAddin, IcoMyOutlookAddin1)
  end;

  TAddInModule = class(TadxCOMAddInModule)
    procedure adxCOMAddInModuleAddInInitialize(Sender: TObject);
    procedure adxCOMAddInModuleAddInFinalize(Sender: TObject);
  private
  protected
    procedure NameSpaceOptionsPagesAdd(ASender: TObject;
      const Pages: PropertyPages; const Folder: MAPIFolder); override;
  public
  end;

var
  adxcoMyOutlookAddin1: TAddInModule;

implementation

{$R *.dfm}

procedure TAddInModule.adxCOMAddInModuleAddInInitialize(Sender: TObject);
begin
  adxcoMyOutlookAddin1 := Self;
end;

procedure TAddInModule.adxCOMAddInModuleAddInFinalize(Sender: TObject);
begin
  adxcoMyOutlookAddin1 := nil;
end;

procedure TAddInModule.NameSpaceOptionsPagesAdd(ASender: TObject;
  const Pages: PropertyPages; const Folder: MAPIFolder);

  function GetFullFolderName(const AFolder: MAPIFolder): string;
  var
    IDisp: IDispatch;
    Folder: MAPIFolder;
  begin
    Result := '';
    Folder := AFolder;
    while Assigned(Folder) do begin
      Result := '\' + Folder.Name + Result;
      try
        IDisp := Folder.Parent;
        if Assigned(IDisp) then
          IDisp.QueryInterface(IID_MAPIFolder, Folder);
      except
        Break;
      end;
    end;
    IDisp := nil;
    Folder := nil;
    if Result <> '' then Delete(Result, 1, 1);
  end;

begin
  if GetFullFolderName(Folder) = 'Personal Folders\Inbox' then
    Pages.Add('MyOutlookAddin1.PropertyPage1', 'My Property Page');
end;

initialization
  TadxFactory.Create(ComServer, TcoMyOutlookAddin1,
	CLASS_coMyOutlookAddin1, TAddInModule);

end.

The add-in module contains two classes: the "interfaced" class (TcoMyOutlookAddin1 in this case) and the add-in module class (TAddInModule). The "interfaced" class is a descendant of the TadxAddIn class that implements the IDTExtensibility2 interface required by the COM Add-in architecture. Usually, you don't need to change anything in the TadxAddIn class.

The add-in module class implements the add-in functionality. It is an analogue of the Data Module, but unlike the Data Module, the add-in module allows you to set all properties of your Outlook add-in, handle its events, and create toolbars and controls.

Step 3. Add-in Express COM Add-in designer

First off, you can drop a component from the Tool Palette onto the designer of the Outlook add-in module.

Also, the module designer allows setting add-in properties. The most important are the name of your add-in (AddInName) and how it loads into the host application (LoadBehavior). The typical value of the LoadBehavior property is 3, which means Loaded and Connected.

The properties of the Outlook add-in module

Step 4. Add a new Explorer CommandBar

To add a command bar to the Outlook Explorer window, use the TadxOlExplorerCommandBar component from the Add-in Express group in the Tool Palette.

Adding a new Outlook Explorer command bar component

Select the Add-in Express Outlook Explorer Command Bar component, and, in the Object Inspector window, specify the commandbar name using the CommandBarName property and choose its position. Outlook-specific versions of the Command Bar component provides context-sensitive properties. They are FolderName, FolderNames, and ItemTypes (see Command bar visibility rules).

Outlook Explorer command bar properties

In the screenshot, you can see the Outlook Explorer command bar component that will create the command bar named AdxOlExplorerCommandBar1. The command bar will be shown for every Outlook folder (FolderName = ''), the default item types of which are Mail or Task.

Step 5. Add a new CommandBar button to the Outlook add-in

You run the property editor for the Controls property in the Object Inspector. The editor allows adding command bar controls in an intuitive way.

Adding a new button using the visual designer

Add a button to the toolbar, specify the Caption and set Style to adxMsoButtonIconAndCaption. To handle the Click event, in the Object Inspector window, switch to Events and add a Click event handler.

Step 6. Access Outlook objects

Add-in Express provides the OutlookApp property of the TOutlookApplication type for Outlook add-ins. This allows you to write the following code to the Click event of the newly added button.


procedure TAddInModule.DefaultActionInExplorer(
  Sender: TObject);
var
  IExplorer: _Explorer;
begin
  IExplorer := OutlookApp.ActiveExplorer;
  if Assigned(IExplorer) then
    begin
      ShowMessage('The subject is:' + CRLF + GetSubject(IExplorer));
      IExplorer := nil;
    end;
end;

function TAddInModule.GetSubject(
  const ExplorerOrInspector: IDispatch): string;
var
  IExplorer: _Explorer;
  ISelection: Selection;
  IInspector: _Inspector;
begin
  Result := '';
  if (ExplorerOrInspector <> nil) then
  begin
    ExplorerOrInspector.QueryInterface(IID__Explorer, IExplorer);
    if Assigned(IExplorer) then
      try
        try
          ISelection := IExplorer.Selection;
        except
          ISelection := nil;
          //skip an exception generated by Outlook when some 
          //folders are selected
        end;
        if Assigned(ISelection) then
          try
            if ISelection.Count > 0 then
              Result :=  OleVariant(ISelection.Item(1)).Subject;
          finally
            ISelection := nil;
          end;
      finally
        IExplorer := nil;
      end
    else
    begin
      ExplorerOrInspector.QueryInterface(IID__Inspector, IInspector);
      if Assigned(IInspector) then
      try
        Result := OleVariant(IInspector.CurrentItem).Subject;
      finally
        IInspector := nil;
      end;
    end;
  end;
end;

The code of the GetSubject method emphasizes the following:

  • Outlook fires an exception when you try to obtain the Selection object in some situations.
  • There may be no items in the Selection object.

Step 7. Handle Outlook events

Add-in Express provides several components that make host's events available for the add-in module. To add Outlook events to the add-in, find the TadxOutlookAppEvents component in the Tool Palette and drag-n-drop it onto the module. You can use the component to get access to the events of all Outlook versions. If both TAddInModule and TadxOutlookAppEvents provide the same event, you should use the event provided by TAddInModule. For instance, both TAddInModule and TadxOutlookAppEvents provide the BeforeFolderSwitch event. According to the rule, we choose the event provided by the add-in module and write the following code:


procedure TAddInModule.adxCOMAddInModuleOLExplorerBeforeFolderSwitch (
  ASender: TObject; const NewFolder: IDispatch; var Cancel: WordBool);
begin
  if (NewFolder <> nil) then
    ShowMessage('You are switching to the '
      + (NewFolder as MAPIFolder).Name + ' folder');
end;

Step 8. Add a new Inspector CommandBar

Considering the specificity of Outlook, Add-in Express provide a special command bar component, TadxOlInspectorCommandBar, that offers the same capabilities as its Explorer counterpart: it adds custom command bars or connects to built-in ones in the Outlook Inspector windows. The component adds context-sensitivity to your command bars through the FolderName(s) and ItemTypes properties.

Adding a new Outlook Inspector commandbar component

We use the default settings of the component in this sample. You should populate an Inspector command bar with controls the way it's described in Step 5. Adding a new command bar button. Add a button to the command bar and display the subject of the currently open item using the following code that handles the Click event of the button:


procedure TAddInModule.DefaultActionInInspector(
  Sender: TObject);
var
  IInspector: _Inspector;
begin
  IInspector := OutlookApp.ActiveInspector;
  if Assigned(IInspector) then
    begin
      ShowMessage('The subject is:' + CRLF + GetSubject(IInspector));
      IInspector := nil;
    end;
end;

Note. To display an Inspector command bar in Office 2007 and Office 2010 you must explicitly set the UseForRibbon property of the command bar component to True.

Step 9. Customize Outlook menu bar

Outlook 2000-2003 provides two main menu types for corresponding Outlook windows: Explorer and Inspector. Accordingly, Add-in Express provides two main menu components: Explorer Main Menu component and Inspector Main Menu component (note the Ribbon UI replaces the main menu of Inspector windows in Outlook 2007 and all main menus in Outlook 2010 - 2021). You add them using the context menu of the add-in module. Then you use the visual designer provided for the Controls property of the component.

Customizing the Outlook main menu

For example, to add a custom control to the popup shown by the File | New item in all Outlook Explorer windows, you do the following:

  • Use our free Built-in Control Scanner to scan the command bars and controls of Outlook. The screenshot below shows the result of scanning. You will need the Office IDs from the screenshot below to bind Add-in Express controls to them:
  • IDs of the Outlook commandbar controls

  • Add a popup control to the menu and set its OfficeId property to 30002
  • Add a popup control to the popup control above and set its OfficeId to 30037
  • Add a button to the popup above and specify its properties.

In the sample add-in described here, the BeforeId property of the My Item button is set to 1757, which is the ID of the Mail Message item. In this way, we position our item before Mail Message.

See also Using built-in command bar controls.

Step 10. Customize Outlook context menus

You customize Outlook context menus via the Context Menu component of Add-in Express. You use the context menu of the add-in module to add such a component onto the module. Then you choose Outlook in the SupportedApp property of the component. Then, in the CommanBarName property, you choose the context menu you want to customize. Finally, you add custom controls in the visual designer supplied for the Controls property.

The sample add-in described on this page adds a custom item to the Folder Context Menu command bar that implements the context menu which is shown when you right-click a folder in the folder tree.

Note. Outlook 2000 context menus are not customizable.

Outlook 2010 context menus are customizable using TadxContextMenu (with some limitations) and TadxRibbonContextMenu.

Outlook 2013 context menus are customizable only using TadxRibbonContextMenu.

Also, you can customize many Ribbon-based context menus in Outlook 2010 - 2021. Find the TadxRibbonContextMenu component on the Tool Palette and drop it on the add-in module. The component allows specifying Ribbons that supply context menu names for the ContextMenuNames property. You use the ContextMenuNames property editor to choose the context menu(s) that will display your custom controls specified in the Controls property.

Ribbon context menu properties

Specifying the context menu names

Step 11. Handle events of Outlook Items object

The Outlook 2000 unit provides the TItems component (of the TOleServer type). This component provides the following events: OnItemAdd, OnItemChange, and OnItemRemove. To process these events, you add the following stuff to the Add-in Module:


  TAddInModule = class(TadxCOMAddInModule)
  private
	...
    procedure ItemsAdd(ASender: TObject; const Item: IDispatch);
    function GetIsFolderTracked: boolean;
    procedure SetIsFolderTracked(const Value: boolean);
	...
  public
	...
    Items: TItems;
    property IsFolderTracked: boolean read GetIsFolderTracked write SetIsFolderTracked;
	...
  end;
...
procedure TAddInModule.adxCOMAddInModuleAddInStartupComplete(Sender: TObject);
begin
  IsFolderTracked := true;
end;

procedure TAddInModule.adxCOMAddInModuleAddInBeginShutdown(Sender: TObject);
begin
  IsFolderTracked := false;
end;

procedure TAddInModule.SetIsFolderTracked(const Value: boolean);
begin
  if Assigned(ItemsEvents) then
  begin
    if not Value then
    begin
      ItemsEvents.Disconnect;
      ItemsEvents.Free;
      ItemsEvents := nil;
    end;
  end
  else if Value then
  begin
    ItemsEvents := TItems.Create(Self);
    ItemsEvents.OnItemAdd := ItemsAdd;
    ItemsEvents.ConnectTo(
      Self.OutlookApp.GetNamespace('MAPI').
      	GetDefaultFolder(olFolderInbox).Items);
  end;
end;

function TAddInModule.GetIsFolderTracked: boolean;
begin
  if Assigned(ItemsEvents) then
    Result := Assigned(ItemsEvents.DefaultInterface)
  else
    Result := false;
end;

procedure TAddInModule.ItemsAdd(ASender: TObject; const Item: IDispatch);
var
  S: WideString;
begin
  S := '';
  try
    S := OleVariant(Item).Subject;
  except
  end;
  if (S <> '') then
    ShowMessage('The item with subject "' + S
      + '" has been added to the Inbox folder');
end;

Step 12. Add folder property pages

Outlook allows you to add custom option pages to the Options dialog box (the Tools | Options menu) and / or to the Properties dialog box of any folder. To automate this task, the Add-in Express wizard provides you with the Option Pages window (see Step 1. Building an Outlook COM add-in project).

By default, an option page contains two controls only: a label and an edit box. The edit box shows how to handle the OnChange event and update the corresponding option page.


procedure TcoPropertyPage1.Edit1Change(Sender: TObject);
begin
  GetPropertyPageSite;
  // TODO - put your code here
  UpdatePropertyPageSite;
end;

You add the TCheckBox component to the Property page, handle its OnClick event following the code template above, and connect or disconnect the TItems component in the Apply method. You initialize the check box in the Initialize method of the property page:


function TcoPropertyPage1.Apply: HResult;
begin
  adxcoMyOutlookAddin1.IsFolderTracked  := CheckBox1.State = cbChecked; 
  FDirty := False;
  Result := S_OK;
end;

procedure TPropertyPage1.Initialize;
begin
  ...
  if (adxcoMyOutlookAddin1.IsFolderTracked) then
  begin
   if (CheckBox1.State <> cbChecked) then
    CheckBox1.State := cbChecked;
  end
  else
    if (CheckBox1.State <> cbUnchecked) then
     CheckBox1.State := cbUnchecked;
end;

Step 13. Intercept keyboard shortcut

To intercept a keyboard shortcut, you add an ADXKeyboardShortcut component to the COM Add-in Module using the Add Keyboard Shortcut command of the module.

Adding the Outlook Keyboard Shortcut component

In the Object Inspector window you select (or enter) the desired shortcut in the ShortcutText property. We chose the shortcut for the Send button in the mail Inspector's Standard command bar. It is Ctrl+Enter.

To use keyboard shortcuts, set the HandleShortcuts property of the add-in module to true.


procedure TAddInModule.adxKeyboardShortcut1Action(Sender: TObject);
begin
  ShowMessage('You`ve pressed ' +
    TadxKeyboardShortcut(Sender).ShortcutText);
end;

Step 14. Customize the Outlook Ribbon user interface

To add a new tab to the Outlook Ribbon, you add the TadxRibbonTab component to the module.

Then, in the Object Inspector window, run the editor for the Controls collection of the Ribbon tab component. In the editor, use the toolbar buttons or context menu to add or delete Add-in Express components that form the Ribbon interface of your add-in. First, you add a Ribbon tab and change its caption to My Ribbon Tab. Then, you select the tab component, add a Ribbon group, and change its caption to My Ribbon Group. Next, you select the group, and add a button. Set the button caption to My Ribbon Button. Use the Glyph property to set the icon for the button.

Ribbon tab visual designer

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


procedure TAddInModule.adxRibbonTab1Controls0Controls0Controls0Click(
	Sender: TObject; const RibbonControl: IRibbonControl);
var
  IExplorer: _Explorer;
  Window: IDispatch;
begin
    Window := OutlookApp.ActiveWindow;
    if Window <> nil then begin
      Window.QueryInterface(IID__Explorer, IExplorer);
      if Assigned(IExplorer) then
        DefaultActionInExplorer(nil)
      else
        DefaultActionInInspector(nil);
    end;
end;

Remember, the TadxRibbonTab Controls editor perform the XML-schema validation automatically, so from time to time you will run into the situation when you cannot add a control to some Ribbon level. It is a restriction of the Ribbon XML-schema.

Unlike other Ribbon-based applications, Outlook has numerous ribbons. Please use the Ribbons property of your TadxRibbonTab components to specify the ribbons you customize with your tabs.

Step 15. Add advanced Outlook regions

You add an Outlook Forms Manager component (TadxOlFormsManager) to your add-in module and an Add-in Express Outlook Form to your project using the New Items dialog. Then you add an item to the Items collection of the manager and specify the following properties:

  • ExplorerItemTypes = expMailItem - your custom form will be shown for all mail folders
  • ExplorerLayout = elBottomSubpane - an instance of the form will be shown below the list of mails in Outlook Explorer windows
  • InspectorItemTypes = insMail - your task pane will be shown whenever you open an e-mail
  • InspectorLayout = ilBottomSubpane - an instance of the form will be shown to the right of the message body
  • AlwaysShowHeader = True - the header containing the icon (a 16x16 .ico) and the caption of your form (see the Icon and Caption properties of your form) will be shown for your form even if it is a single form in the given region
  • CloseButton = True - the header of your custom form will contain the Close button; a click on it generates the OnADXBeforeCloseButtonClick event of the form
  • FormClassName =TadxOlForm1 - the class name of the form whose instances will be shown in the regions specified by the ExplorerLayout and/or InspectorLayout properties

On the form, you add a label and handle, say, the OnADXSelectionChange event of the form:

Configuring the advanced region's properties


procedure TadxOlForm1.adxOlFormADXSelectionChange(Sender: TObject);
begin
  RefreshMe();
end;

procedure TadxOlForm1.RefreshMe;
var
  module: TAddinModule;
begin
  module := (self.AddinModule as TAddinModule);
  if (self.InspectorObj <> nil) then
    Label1.Caption := module.GetSubject(self.InspectorObj)
  else if (self.ExplorerObj <> nil) then
    Label1.Caption := module.GetSubject(self.ExplorerObj);
end;

The GetSubject method above retrieves the subject of the e-mail currently open in the Outlook Inspector window or the one selected in the current Explorer window.

Read more about creating custom task panes.

Step 16. Run the Outlook add-in

Save the add-in project, compile it, close Outlook, and register the add-in using the Run | Register ActiveX Server menu item. Run Outlook and find your option page, command bars, and controls. You find your add-in in the COM Add-ins dialog.

A custom ribbon tab and a form in the Outlook 2010 Explorer window:

The add-in's UI in Outlook Explorer

A custom ribbon tab and a form in the Outlook 2010 Inspector window:

The add-in's UI in Outlook Inspector

Step 17. Debugging the Outlook add-in

To debug your add-in, specify the add-in's host application in the Host Application field in the Project Options window.

Debugging the Outlook add-in

To debug your add-in in 64-bit versions of Outlook, you have to register the add-in DLL using regsvr32; run it from an elevated 64-bit Command Prompt. In addition, you must explicitly specify to run Outlook 64-bit in the dialog window shown above.

Step 18. Deploying the Outlook add-in

Make sure your setup project registers the add-in DLL. Say, in Inno Setup projects you use the 'regserver' command.

Creating Office add-in in Delphi <<

>> Developing Excel RTD servers