Building an Outlook 2007 Form Region with a Managed Add-In

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

Summary: Learn how to use Microsoft Visual C# and Visual Studio 2005 to develop form regions for Outlook 2007. The sample Visual C# Outlook COM add-in and form region show you how to create Internet headers as an adjoining region. (22 printed pages)

Ryan Gregg, Microsoft Corporation

June 2006

**Applies to: **Microsoft Office Outlook 2007, Microsoft Visual Studio 2005

Download

Contents

  • Overview of Outlook 2007 Form Regions

  • Form Regions

  • Using a Custom Template in Visual Studio 2005

  • Designing a Form Region

  • Hooking Up an Add-in to a Form Region

  • Creating a Setup Project

  • Conclusion

  • Additional Resources

Overview of Outlook 2007 Form Regions

Microsoft Office Outlook 2007 introduces a new form technology called form regions. Form regions overcome the limitations of customizing Outlook forms by using form pages in a variety of new ways. For example, form regions can be displayed in the Reading Pane, and can be added to standard forms without creating a derived message class. Although form regions do not support embedded script, business logic for a form region is written as an Outlook COM add-in and linked with the form region. This article covers the creation of a sample Outlook add-in that displays transport header information in a form region on e-mail items.

You can create and run forms with form regions without a COM add-in, but using a COM add-in has the benefit of supporting custom business logic or advanced functionality in the form regions.

This article assumes that you have some knowledge of COM add-ins and that you know how to build, deploy, and install a managed COM add-in that is written in Microsoft Visual Basic or Microsoft Visual C#. You should be familiar with the Outlook object model, and should have at least some basic knowledge of the Microsoft .NET Framework and COM interoperability.

Form Regions

In previous versions of Outlook, third parties who wanted to extend the Outlook user interface (UI) to include custom functionality were restricted by limited support for custom forms in Outlook. Often, when you wanted to add a few fields or make a small modification to the form, Outlook required you to redesign the entire form. In Outlook 2007, form regions allow more ways to add UI to standard forms and simplify the process of designing custom UI.

Through an adjoining form region, you can extend any existing form with additional fields or controls. These adjoining form regions are displayed at the bottom of the first page of a form, and each adjoining form region is collapsible. You can also add a separate form region, which is displayed as a full additional form page and can appear on any existing standard form or custom form.

Figure 1. Exchange Unified Messaging form region displayed in the Outlook Reading Pane

Exchange Unified Messaging form region

In addition to adding new UI, you can use a form region to replace existing UI in standard forms and create a new form for a derived message class, as shown in Figure 1. You can register the form region as a replacement form region: If you specify a value of Replace for the <formRegionType> tag in the form region manifest XML file, the form region will replace the default page of the form. If you specify a value of ReplaceAll for the <formRegionType> tag, the form region will replace the entire form, resulting in a new form for a derived message class.

Another benefit of using form regions is that form regions support visual themes. In the past, you were required to use custom Microsoft ActiveX controls or advanced workarounds to enable a themed look to custom forms. With form regions, all of the controls that come with Outlook 2007 inherit the Microsoft Windows theme.

Using a Custom Template in Visual Studio 2005

Microsoft Visual Studio 2005 continues to have built-in support for developing Office add-ins through the Shared add-in template, but this template is missing some key blocks of code that are useful for writing Outlook 2007 COM add-ins in managed code. Although using Microsoft Visual Studio Tools for the Microsoft Office System would be the preferred development approach, it is currently incompatible with Office 2007 applications. In the meantime, you can download the easy-to-use templates that encapsulate the details of the IDTExtensibility2 interface for Outlook add-ins (shown earlier).

To install the custom templates

  1. Download OutlookAddinTemplates.msi.

  2. Double-click the file to start the setup wizard.

  3. Complete the setup steps. The template files are automatically installed to the proper locations.

Now that the custom template is installed, proceed by creating an add-in project using the template.

To create a project in Visual Studio 2005 using this template

  1. In Visual Studio 2005, press CTRL+SHIFT+N to display the New Project dialog box, as shown in Figure 2.

  2. In the Project Types list, click your preferred language (Visual Basic or Visual C#).

  3. In the Templates list, select Office Outlook 2007 Add-in from the My Templates group.

  4. Name the project InternetHeaderAddin and click OK.

Figure 2. New Project dialog box

New Project dialog box

Visual Studio 2005 then uses the custom template to generate a default add-in project for Outlook 2007. This project contains several files that form the basis of an Outlook add-in.

Because you know this add-in will contain a form region, create a folder to store the form region files in your project. To create a new folder in the project, right-click the project in Solution Explorer, point to Add, and then click New Folder. Name the folder Regions.

Now that you have created an add-in project and created a location in which to store your form region, you can switch to Outlook and start designing the form region layout.

Designing a Form Region

Before you start writing the business logic behind a form region, you should design the layout of the form and define all of the controls. You will use Outlook to design your new form region layout.

To design a form region in Outlook

  1. Start Outlook 2007.

  2. On the main menu, point to Tools, click Forms, and then click Design a Form.

  3. Select Message, and then click Open, as shown in Figure 3.

    Figure 3. Design Form dialog box

    Design Form dialog box

  4. In the Design group, click Form Region, and then click New Form Region, as shown in Figure 4.

    Figure 4. Designing a new Form Region

    Designing a new form region

Outlook creates a tab in the Forms Designer titled "(Form Region)." This tab is now a new form region design surface that you will use to design the form region, saving it as an Outlook Form Storage (.ofs) file. For this solution, you need one text box and one button on the form.

To add these controls to the form

  1. Display the Control Toolbox by going to the Design group of the Ribbon UI and clicking Control Toolbox.

  2. Right-click the Toolbox window, and select Custom Controls.

  3. Scroll through the list of controls and select Microsoft Office Outlook Command Button Control and Microsoft Office Outlook TextBox Control, and then click OK, as shown in Figure 5.

    Figure 5. Additional Controls dialog box

    Additional Controls dialog box

  4. Drag a text box and a command button from the Toolbox to the form design surface.

  5. Arrange the controls to look like the example in Figure 6.

    Figure 6. Example form layout

    Example form layout

  6. To adjust the properties of each control, including the control name and caption, right-click each control and select Properties.

    For each control, keep the default settings and adjust the properties accordingly:

    Text box control:

    • Name: TextBoxHeaders

    • Multiline: True

    • Read-only: True

    • Horizontal Layout: Grow/shrink with Form

    Command button control:

    • Name: BtnCopy

    • Caption: &Copy

  7. To save the form region, go to the Design group of the Developer tab, click Form Region, and then click Save Form Region As.

  8. Browse to the location of your add-in project and open the Regions folder that you created earlier. Save the new form region in this folder as InternetHeaderAdjRegion.ofs, and close the window. When Outlook prompts you to save the changes to the item underlying the designer, click No.

Authoring a Form Region Manifest

Now that the design of the form region is complete, you can include the .ofs file in your add-in project and author the XML manifest for the form region. The XML manifest includes information about the form region and how it is displayed to the user.

To include the form region in the add-in project

  1. In the Visual Studio 2005 add-in project created earlier, right-click the Regions folder, point to Add, and then click Existing Item.

  2. Change the Files of Type selector to indicate All Files.

  3. Select the InternetHeaderAdjRegion.ofs file, and click Add.

Next, you need to author the XML manifest, which indicates to Outlook the details about this form region.

To create an XML file in the Regions folder of the project

  1. Right-click the Regions folder, point to Add, and click New Item.

  2. Select XML File, type InternetHeaderAdjRegion.xml for the file name, and then click Add.

  3. Create the manifest file according to the Form Region XML schema, for example:

    <?xml version="1.0" encoding="utf-8" ?>
    <FormRegion xmlns="http://schemas.microsoft.com/office/12/outlook/formregion.xsd">
       <name>InternetHeaderDisplay</name>
       <formRegionType>adjoining</formRegionType>
       <title>Internet Headers</title>
       <showInspectorRead>true</showInspectorRead>
       <showReadingPane>true</showReadingPane>
       <showInspectorCompose>false</showInspectorCompose>
       <addin>InternetHeaderAddin.Connect</addin>
    </FormRegion>
    

For more information about the XML schemas for form regions, see the sections "Form Region Manifest" and "Form Region Localization Manifest" in the 2007 Office System: XML Schema Reference.

Each element in the XML file defines an aspect of how Outlook displays the form region:

  • <name> defines the internal name used by the add-in to refer to this form region.

  • <title> defines the display text used in the adjoining region header.

  • <formRegionType> defines the type of region, in this case an adjoining region.

  • <showInspectorRead> defines whether this region will be shown for read inspectors.

  • <showReadingPane> defines whether this region will be displayed in the Reading Pane.

  • <showInspectorCompose> defines whether this region will be displayed for compose inspectors.

  • <addin> indicates the ProgID of the add-in that this form region is linked with.

Registering a Form Region

To properly register a form region with Outlook, a registry value needs to be added for each form region. This key can go in either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER, based on the solution requirements. For this sample, add a registry key to HKEY_CURRENT_USER.

To add a registry key

  1. Open regedit.exe by clicking Start, and then clicking Run. Type regedit.exe, and then click OK.

  2. Browse to HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook.

  3. If the FormRegions key does not exist, create a new key in this path.

  4. Expand the FormRegions key, and check for a key named IPM.Note. If this key does not exist, create it.

    You might notice other keys, such as IPM.Note.Microsoft.Exchange.Voice. These keys are part of a built-in solution for Exchange Unified Messaging and should not be modified.

  5. Add a new string value under the IPM.Note key, named InternetHeaderAdjRegion.

    Double-click the value name, and type the full path of the manifest XML file, such as C:\Source\InternetHeaderAdjRegion.xml, and then click OK.

    Ensure that the path is a local path. Outlook ignores UNC-based paths for form regions for performance reasons.

Hooking Up an Add-in to a Form Region

Now that you have completed the form region design and created a manifest describing the form region, you are ready to hook up your add-in to work with this form region. When a form region manifest includes the <addin> element, Outlook looks for a COM add-in with the same ProgID and checks to see if the same class that implements the IDTExtensibility2 interface also implements the FormRegionStartup interface. If this interface is implemented, Outlook calls on that interface to obtain the layout information and to provide a reference to the form region when it is displayed.

Adding References

Because form regions are based on the Microsoft Forms 2.0 types, you must add a reference in the add-in project to this type library.

To add the reference

  1. In Solution Explorer, right-click the project node, and then click Add Reference.

  2. In the Add Reference dialog box, click the COM tab, as shown in Figure 7.

  3. Scroll to find Microsoft Forms 2.0 Object Library, select it, and click OK.

    Visual Studio adds a reference to Microsoft.Vbe.Interop.Forms in the project references.

Figure 7. Add Reference dialog box

Add Reference dialog box

Next, add a reference to System.Windows.Forms so that you can access the Clipboard for the Copy button on the form.

To add the reference

  1. In Solution Explorer, right-click the project node and click Add Reference.

  2. In the Add Reference dialog box, click the .NET tab.

  3. Scroll to System.Windows.Forms and click OK.

    Visual Studio will add a reference to System.Windows.Forms to the project.

Managing State

To track multiple instances of a form region, you need a class that holds on to the state information for each form region. The add-in creates a new instance of this class each time a form region is opened, and destroys each instance when the form region is closed. In the add-in project, add a new class named InternetHeaderAdjRegion to your project:

  1. In Solution Explorer, right-click the project node.

  2. Click Add, and then click Class.

  3. Type the name of the new class, InternetHeaderAdjRegion, and then click Add.

Inside the new class, you will define five variables to maintain state, and one event that will be used to communicate back to the parent class that the form region has been closed and the references should be cleaned up. You will also add a constructor that takes a FormRegion object, event handlers for the Region.Closeevent and BtnCopy.Click event, and two helper functions, GetTransportHeaders and ShowRegionOnItem that will help retrieve the information you need to display and determine if the form region should be shown on an item.

To create aliases for the namespace references that will be used in the project, include the following code block at the top of the file.

using System;
using System.Collections.Generic;
using System.Text;
using Outlook = Microsoft.Office.Interop.Outlook;
using Forms = Microsoft.Vbe.Interop.Forms;
Imports Outlook = Microsoft.Office.Interop.Outlook
Imports Forms = Microsoft.Vbe.Interop.Forms

Inside the class, define the instance variables and the event as follows:

class InternetHeaderAdjRegion
    {
        // Instance variables to maintain state.
        private Outlook.FormRegion Region;
        private Forms.UserForm Form;
        private Outlook.OlkTextBox TextBoxHeaders;
        private Outlook.OlkCommandButton BtnCopy;
        private string Headers;

        // Public event for when the region closes.
        public event EventHandler Closed;

    }
Public Class InternetHeaderAdjRegion
    ' Instance variables for state.
    Private WithEvents Region As Outlook.FormRegion
    Private Form As Forms.UserForm
    Private TextBoxHeaders As Outlook.OlkTextBox
    Private WithEvents BtnCopy As Outlook.OlkCommandButton
    Private Headers As String

    ' Public event for when the region closes.
    Public Event Closed As EventHandler

End Class

Next, you need to hook up references for all of the objects we care about. To access the controls on the form, define a new variable for the Forms 2.0 UserForm object. This is returned when you get the value of the Form property on the FormRegion object. From this, the add-in obtains references to each individual control on the form by accessing the Controls collection on the Formobject. Then, hook up event handlers to the Region.Close event and the BtnCopy.Click event. Set the Text property of the text box control to the value of the transport headers, so that they are displayed to the user. All of this work happens in the constructor for this class. You define the GetTransportHeaders method later on.

public InternetHeaderAdjRegion(Outlook.FormRegion region)
{
    Region = region;
    Region.Close += 
        new Outlook.FormRegionEvents_CloseEventHandler(Region_Close);

    Form = (Forms.UserForm)region.Form;

    Headers = GetTransportHeaders(Region.Item);

    TextBoxHeaders =
        (Outlook.OlkTextBox)Form.Controls.Item("TextBoxHeaders");
    TextBoxHeaders.Text = Headers;
    BtnCopy = (Outlook.OlkCommandButton)Form.Controls.Item("BtnCopy");

    BtnCopy.Click += 
    new Outlook.OlkCommandButtonEvents_ClickEventHandler(BtnCopy_Click);
}
Public Sub New(ByVal Region As Outlook.FormRegion)
    Me.Region = Region

    Form = DirectCast(Region.Form, Forms.UserForm)

    TextBoxHeaders = DirectCast(_
        Form.Controls.Item("TextBoxHeaders"), Outlook.OlkTextBox)
    BtnCopy = DirectCast(_
        Form.Controls.Item("BtnCopy"), Outlook.OlkCommandButton)
    Headers = GetTransportHeaders(Region.Item)
    TextBoxHeaders.Text = Headers
End Sub

Next, add the code behind the event handlers defined in the constructor. For the BtnCopy_Click event handler, copy the current headers to the Clipboard. Because the .NET Framework provides System.Windows.Forms.Clipboard, use this class to copy the headers. The SetText method will set the Clipboard value to a given string. A try/catch block is used to make sure that no errors are thrown back to Outlook if this method fails.

void BtnCopy_Click()
{
    try
    {
        System.Windows.Forms.Clipboard.SetText(Headers);
    }
    catch { }
}
Private Sub BtnCopy_Click() Handles BtnCopy.Click
    Try
        System.Windows.Forms.Clipboard.SetText(Headers)
    Catch
    End Try
End Sub

The second event handler to hook up is for Region_Close. Outlook raises this event when the form region is closed, either because the Inspector window closed or the Reading Pane is no longer displaying the item. In this event handler, you want to clean up all the state references, unhook the event handlers, and raise the Closed event to notify the parent about the change.

void Region_Close()
{
    // Unhook events.
    BtnCopy.Click -= new Outlook.OlkCommandButtonEvents_ClickEventHandler(BtnCopy_Click);

    // Remove references.
    BtnCopy = null;
    TextBoxHeaders = null;
    Headers = null;
    Form = null;
    Region = null;

    // Fire event to the parent.
    if (Closed != null)
        Closed(this, EventArgs.Empty);
}
Private Sub Region_Close() Handles Region.Close
    ' Remove our references.
    BtnCopy = Nothing
    TextBoxHeaders = Nothing
    Headers = Nothing
    Form = Nothing
    Region = Nothing

    ' Raise the closed event.
    RaiseEvent Closed(Me, EventArgs.Empty)
End Sub

You already used GetTransportHeaders in the constructor, so you need to define what this method does. GetTransportHeaders uses the new Outlook PropertyAccessor object to read the PR_TRANSPORT_MESSAGE_HEADERS property from the item. This property is not exposed through the Outlook object model, but the PropertyAccessor object enables you to read it without using another API. Because this helper method does not reference any of the instance variables, it is defined as static. A try/catch block is again used to catch any errors and to fail gracefully. You also add an internal method that will be called from the Connect class to determine whether or not to show the form region. The code determines this based on whether there are any transport headers defined.

static string GetTransportHeaders(object Item)
{
    const string PR_TRANSPORT_MESSAGE_HEADERS = 
        "http://schemas.microsoft.com/mapi/proptag/0x007D001E";
    try
    {
        OutlookItem olkItem = new OutlookItem(Item);
        Outlook.PropertyAccessor propAccessor = 
            olkItem.PropertyAccessor;

        string internetHeaders = (string)propAccessor.GetProperty(
            PR_TRANSPORT_MESSAGE_HEADERS);
        return internetHeaders;
    }
    catch
    {
        return null;
    }
}

internal static bool ShowRegionOnItem(object Item) 
{
    string headers = GetTransportHeaders(Item);
    if (headers == null || headers.Length == 0)
        return false;
    else
        return true;
}
Public Shared Function GetTransportHeaders(ByVal Item As Object) As String
    Try
        Dim olkItem As New OutlookItem(Item)
        Dim propAccessor As Outlook.PropertyAccessor = _
        olkItem.PropertyAccessor
        Dim internetHeaders As String = _
        CStr(propAccessor.GetProperty(_
        "http://schemas.microsoft.com/mapi/proptag/0x007D001E"))
        Return internetHeaders
    Catch
        Return Nothing
    End Try
End Function

Shared Function ShowRegionOnItem(ByVal Item As Object) As Boolean
    Dim headers As String = GetTransportHeaders(Item)
    Return Not String.IsNullOrEmpty(headers)
End Function

For more information about the PropertyAccessor object, see What's New for Developers in Outlook 2007 (Part 2 of 2) and the Outlook 2007 Developer Reference, available on MSDN.

Now that you have a class to maintain the state of a single form region instance, you can use this class and a collection in the Connect class to maintain the state of multiple form regions over the lifetime of the add-in.

Implement Outlook.FormRegionStartup

Now you can start hooking up the FormRegionStartup interface and making the form region solution come alive. To begin, open the Connect class from the add-in project. This class was created by the Outlook add-in template and is the class that implements the IDTExtensibility2 interface. To enable this add-in to work with form regions, you need to also implement the FormRegionStartup interface by adding the interface to the class definition.

/// <summary>
/// The object that implemented the Outlook add-in interface.  
/// The additional logic that implements IDTExtensibility2 is contained
/// in Connect.Designer.cs
/// </summary>
/// <see also class="IDTExtensibility2" />
public partial class Connect : Outlook.FormRegionStartup
{ 
     /// Leave existing code intact.
     ...

     #region FormRegionStartup Members

     void BeforeFormRegionShow(Outlook.FormRegion FormRegion)
     {
            
     }

     object GetFormRegionStorage(string FormRegionName, object Item,
        int LCID, Outlook.OlFormRegionMode FormRegionMode,
        Outlook.OlFormRegionSize FormRegionSize)
     {
            
     }

     #endregion
}
''' <summary>
''' The object that implemented the Outlook add-in interface.  
''' The additional logic that implements IDTExtensibility2 is contained
''' in Connect.Designer.vb
''' </summary>
''' <remarks></remarks>
Partial Public Class Connect
    Implements Outlook.FormRegionStartup

    ' Keep existing code intact.
    ...

#Region "FormRegionStartup members"

    Public Sub BeforeFormRegionShow(FormRegion As _ 
       Outlook.FormRegion) _ 
       Implements Outlook._FormRegionStartup.BeforeFormRegionShow

    End Sub

    Public Function GetFormRegionStorage( _ 
       ByVal FormRegionName As String, ByVal Item As Object, _
       ByVal LCID As Integer, ByVal FormRegionMode As _
       Outlook.OlFormRegionMode, FormRegionSize As _
       Outlook.OlFormRegionSize) As Object _
       Implements Outlook._FormRegionStartup.GetFormRegionStorage

    End Function
#End Region
End Class

The two methods defined in this interface are called as Outlook loads an item and prepares to show a form. When Outlook starts to load the UI for a message class that has a form region registered, it first calls the GetFormRegionStorage method to load the layout information for the form region. GetFormRegionStorage should return either a string (which is the path to the .ofs file), an IStorage instance for the contents of the .ofs file, or a byte array that contains the contents of the .ofs file. Later, just before Outlook displays the form region to the user, it calls the BeforeFormRegionShow method, and passes a reference to the form region object.

First write the code for the GetFormRegionStorage method. The best practice here is to be able to embed the .ofs file in your add-in so that it cannot be modified by the user or other programs. One of the formats accepted by Outlook is a byte array, so you can use the .NET Framework resource system to embed the .ofs file in your add-in:

  1. Right-click the project in Solution Explorer, and select Properties.

  2. Click the Resources tab, and then click the hyperlink to create a default resource file if you have not yet created a resource file for the project.

  3. Press Ctrl+5 to show file-based resources.

  4. Drag InternetHeaderAdjRegion.ofs from Solution Explorer into the resource list view to add it as a resource.

  5. Save the project settings and close the project tab.

Now, in the GetFormRegionStorage method in theConnect class, you make a call to ShowRegionOnItem to check whether to show the region. If the code finds that the message contains transport headers, it will return a byte array containing the contents of the .ofs file. If there are no headers, it returns Null, which indicates to Outlook not to load the form region for this item.

public object GetFormRegionStorage(string FormRegionName, object Item,
    int LCID, Outlook.OlFormRegionMode FormRegionMode, 
    Outlook.OlFormRegionSize FormRegionSize)
{
    if (FormRegionName == "InternetHeaderDisplay" && 
        InternetHeaderAdjRegion.ShowRegionOnItem(Item))
    {
        // Return the storage only when there are headers.
        return Properties.Resources.InternetHeaderAdjRegion; 
    }

    return null;
} 
Public Function GetFormRegionStorage( _ 
   ByVal FormRegionName As String, ByVal Item As Object, _
   ByVal LCID As Integer, ByVal FormRegionMode As _
   Outlook.OlFormRegionMode, FormRegionSize As _
   Outlook.OlFormRegionSize) As Object _
   Implements Outlook._FormRegionStartup.GetFormRegionStorage

   If FormRegionName = "InternetHeaderDisplay" AndAlso _
           InternetHeaderAdjRegion.ShowRegionOnItem(Item) Then
             ' Return the storage only when there are headers   
       Return My.Resources.InternetHeaderAdjRegion
   End If

   Return Nothing

End Function

Visual Studio 2005 automatically generates the Properties.Resources.InternetHeaderAdjRegion (or My.Resources.InternetHeaderAdjRegion) hierarchy based on the resources defined in the project. This provides a byte array exactly as Outlook expects.

If you were to compile and run the project as it is right now, you would see the form region appear on all IPM.Note items that have transport headers. However, no data would appear in the text box and the button would not have any action. You still need to hook up the state management class to the instance of a form region. You can do this using the BeforeFormRegionShow method of the FormRegionStartup interface.

To track multiple open form regions (if there are multiple Inspectors or Explorer windows), you need to maintain a collection of the form region instances. To do this, you use a list collection, a .NET generic collection class, typed to your state management class, InternetHeaderAdjRegion. First, define the collection as an instance variable in your class. Put this code block at the top of Connectclass:

private List<InternetHeaderAdjRegion> OpenRegions = 
    new List<InternetHeaderAdjRegion>();
Private OpenRegions As New List(Of InternetHeaderAdjRegion)

Next, write some code in the BeforeFormRegionShow method to create a new instance of the InternetHeaderAdjRegion, and pass it the form region that is about to be shown. The state management class will then initialize the region and set the Text property of the text box to your transport headers. At the same time, a new event handler is created to handle the Closed event on the state management class. Remember, this event is raised when the form region is no longer being displayed to the user, and you should clean up the reference. In this case, you simply remove the instance of the class from the OpenRegions collection and let garbage collection take care of the rest.

public void BeforeFormRegionShow(Outlook.FormRegion FormRegion)
{
    if (FormRegion.InternalName == "InternetHeaderDisplay")
    {
        InternetHeaderAdjRegion newRegion = new 
            InternetHeaderAdjRegion(FormRegion);
        newRegion.Closed += new EventHandler(Region_Closed);

        OpenRegions.Add(newRegion);
    }
}

void Region_Closed(object sender, EventArgs e)
{
    OpenRegions.Remove(sender as InternetHeaderAdjRegion);
}
Public Sub BeforeFormRegionShow( ByVal FormRegion As _
    Microsoft.Office.Interop.Outlook.FormRegion) Implements _
    Microsoft.Office.Interop.Outlook.FormRegionStartup._
    BeforeFormRegionShow
    If FormRegion.InternalName = "InternetHeaderDisplay" Then
        Dim newRegion As New InternetHeaderAdjRegion(FormRegion)
        AddHandler newRegion.Closed, AddressOf Region_Closed
        OpenRegions.Add(newRegion)
    End If
End Sub

Private Sub Region_Closed(ByVal sender As Object, ByVal e As EventArgs)
    OpenRegions.Remove(DirectCast(sender, InternetHeaderAdjRegion))
End Sub

Running the Add-In

At this point, you should compile the project and make sure there are no errors. Next, you need to adjust the project properties to enable F5 debugging with Outlook.

To edit the project properties

  1. Right-click the project node in Solution Explorer, and select Properties.

  2. Click the Debug tab.

  3. Select Start external program and type the path to the Outlook.exe file, for example, C:\Program Files\Microsoft Office\Office12\outlook.exe.

  4. Change the Working directory value to be the path Outlook.exe resides in, for example, C:\Program Files\Microsoft Office\Office12\.

  5. Save the project and close the Properties tab.

The last step is to register the add-in with Outlook. The add-in template provided with this article automatically generates a .reg file with the necessary settings to register the COM add-in created by the project with Outlook.

To merge this file with your registry

  1. Open Windows Explorer and navigate to the project directory.

  2. Double-click the addin_registry.reg file.

  3. Click Yes to merge the changes with the registry.

  4. Press F5 to compile your add-in and start Outlook with the debugger attached.

  5. Click an e-mail message you received from the Internet. You should see an adjoining form region with the transport headers, as shown in Figure 8.

  6. Click Copy to copy the contents of the transport headers to the Clipboard.

Figure 8. An adjoining region displaying transport headers

An adjoining region displaying transport headers

Creating a Setup Project

Now that you have learned how to build an add-in that uses form regions to provide a solution with a custom UI in Outlook, you can deploy that add-in on other computers. The best means for deploying an add-in solution is to build a setup project and distribute an installer package. There are several important considerations you need to remember when building your setup project:

  • You must install the Microsoft .NET Framework on the target computer before you install your add-in.

  • You must install the Office primary interop assemblies on the target computer. These are automatically installed with Office if the .NET Framework was installed before Office 2007. If the .NET Framework is installed later, these components can be installed by repairing the Office 2007 installation.

  • You must install the form region XML manifest on the computer's disk so that Outlook can find it.

  • You must write the form region registry value that points to the XML manifest in the location it was installed on the computer.

  • You must write the necessary registry values to register the add-in with Outlook.

The setup project provided in Visual Studio 2005 makes this easier.

To create a setup project in the add-in solution

  1. Press CTRL+SHIFT+N to create a project.

  2. In the Project types list, expand Other Project Types, and select Setup and Deployment.

  3. Click Setup Project.

  4. Change the Solution drop-down list to Add to Solution.

  5. Type a display name for the project, for example, InternetHeaderAddinSetup.

  6. Click OK.

After Visual Studio creates the setup project, it opens the File System view for the setup project. Then you can add the files you want to write to the file system, including:

  • Form Region XML Manifest

  • Add-in Primary Output

To add these files to the setup project

  1. In the file system on Target Machine tree view, select the Application folder.

  2. Right-click in the file list, point to Add, and then click Project Output.

  3. Click Primary Output, and make sure Project is set to InternetHeadersAddin, and then click OK.

  4. Several files are added to the file view. Exclude the following three files:

    • Microsoft.Office.Interop.Outlook.dll

    • Microsoft.Vbe.Interop.Forms.dll

    • Office.dll

  5. To exclude each DLL, select DllName.dll in the file list and press F4 to display the properties, then change the Exclude property to True. Repeat this step to exclude each DLL file.

  6. Right-click in the file view, point to Add, and click Project Output.

  7. Click Content Output, and make sure Project is set to InternetHeadersAddin, and then click OK.

Now that the project contains all of the necessary files, you need to add the appropriate registry entries to make Outlook discover the add-in and the form region. To edit which registry keys are configured when the installer is run, click View, point to Editor, and click Registry. This displays the Registry Editor for the setup project. Use the variable [TARGETDIR] to indicate the directory into which the add-in will be installed. This allows a relative path to be used for the XML manifest location.

To register the form region and the add-in

  1. Right-click Registry on Target Machine and select Import.

  2. Browse to the project directory and select addin_registry.reg, then click OK.

  3. Expand HKEY_CURRENT_USER, expand Microsoft, expand Office, and then expand Outlook.

  4. Right-click the Outlook node, point to New, and click Key.

  5. Type FormRegions and press Enter.

  6. Right-click the FormRegions node, point to New, and click Key.

  7. Type IPM.Note and press Enter.

  8. Right-click the IPM.Note node, point to New, and click String Value.

  9. Change the value name to InternetHeaderAdjRegion.

  10. Press F4 to display the value properties page and change the Value property to [TARGETDIR]InternetHeaderAdjRegion.xml.

  11. Save the setup project.

Finally, you need to make sure that the .NET Framework is installed before the add-in. Fortunately, Visual Studio makes this easy.

To adjust the prerequisites for the installer

  1. Click Project, and then click Properties.

  2. Click Prerequisites.

  3. Verify that the .NET Framework 2.0 appears in the list of components.

  4. Click OK, and then click OK again.

Now you can build the setup project and test the installation package.

Conclusion

In addition to a multitude of other new features and functionality in the Outlook 2007 object model, form regions provide a powerful and simple way to customize the Outlook UI in ways that were previously not possible with Outlook. Form regions also enable you to use a rich and familiar development environment to write business logic and other code running behind forms instead of restricting you to Notepad and Microsoft Visual Basic Scripting Edition (VBScript). If you have a forms-based solution, you should consider migrating your solutions to Outlook 2007 to use form regions.

Additional Resources