Published Tuesday, September 19, 2006 5:15 AM by martin

Outlook 2007 Form Region Add-ins

With Outlook 2007 it's possible to define a piece of UI that appears inside Outlook's inspector windows, either for all items or just for items of a specific type (such as messages or appointments).  We call these UI extensions Form Regions.  The exact process by which the code for a Form Region gets loaded is something I confess I found somewhat confusing, so this post is my attempt to explain it.  There's an article here, which is longer and better :-)  You'll want to be using Visual Studio Tools for Office 2005, Second Edition, which is currently available in Beta form here.

1. Registry

Outlook uses the registry to identify and locate add-ins, and so too for form region code.  However, it manages them both somewhat differently...

Add-ins are configured under HKCU\Software\Microsoft\Office\Outlook\Addins, or the corresponding location under HKLM.  Each add-in is configured as a separate sub-key with the same name as the add-in, and those subkeys contain values that point to the implementation of the add-in code.

Form region code is configured under HKCU\Software\Microsoft\Office\Outlook\FormRegions, or the corresponding location under HKLM.  The sub-keys relate to different Outlook item classes, for example IPM.Note.  Under each item class, there is one value for each Form Region extension, pointing to an XML file.  The XML file for a Form Region is known as the Form Region Manifest.  You can get the schema for this file, as well as many other Office 2007 schemas, here.

2. Add-in Loading

I'm specifically talking about COM add-ins here.  I mean, I'd be writing managed code, but Outlook will load my add-in as a COM add-in, via some interop technology that I need not concern myself with.  Under the add-in's registry key, there's a reference either to the DLL that implements the add-in, or to a manifest file that describes how to load the add-in.  The COM class that implements the add-in has to implement the COM interface called IDTExtensibility2, or preferably you use VSTO and don't worry about such things :-) I don't think this has changed for Outlook 2007, so I won't go into that any further here.

3. Form Region Loading

Form Region extension code must reside in an add-in.  Outlook reads the Form Region manifest file, and finds the <addin> element, which contains a COM ProgId.  Outlook then tries to find a loaded add-in with that same ProgId, and queries it for the COM interface called  _FormRegionStartup.  In practice, you'll be using VSTO 2005 SE, and this simply means that your Connect class needs to inherit from Outlook.FormRegionStartup.

This interface defines a couple of methods that Outlook will call each time an inspector is opened that needs an instance of your Form Region...

The first is called GetFormRegionStorage.  From this you need to return the content of the .ofs file that Outlook saved when you designed the Form Region (oh yes, you need to do the visual design in Outlook - see the article I referenced earlier).  The easiest way to return this content is to build the .ofs file into your add-in as an embedded resource.  The sample code for that MSDN article shows how to do this.

The second method is called BeforeFormRegionShow.  This is your opportunity to set up any state that's specific to one instance of your Form Region.  I mean, Outlook might open any number of inspectors that all contain your Form Region; you'll want to know that you can tell which is which.  The best approach is to create a class that encapsulates each instance and keep all your state in there.  The other thing you'll probably want to do in this method is attach an event handler to the closed event for the Form Region, allowing you to clean up any state.

So what kind of state might you want to keep for each instance of your Form Region?  Well, perhaps the most important thing is that you'll need to grab a reference to each control displayed in the Form Region, so that you can set their content programmatically.  Outlook hands you an object of type FormRegion.  You can get its Form property to find the parent form.  From there you can do form.Controls.Item("<item_id>") to get hold of any control in your Form Region.

Now Read the Article

I'll reference it again... this article shows all this stuff and refers to some sample code.  Hopefully, between that article, this post, and the sample code, you should work it all out :-)