GetFormRegionIcon and GetFormRegionManifest

The Outlook FormRegionStartup interface was enhanced right before Office 2007 was released. Two new methods were added. The existing documentation doesn’t explain these methods in any detail – not even in the developer help within Office. The existing VSTO documentation does include mention of the two new methods, but doesn’t explain how to use them. It does, however, explain how to create a VSTO add-in for Outlook 2007 implementing the FormRegionStartup interface:

https://msdn2.microsoft.com/en-us/library/aa942741(VS.80).aspx

I’ll assume you can refer to that article to get the basic form region add-in built, so in this post I’ll only talk about the changes you need to make to implement the two new methods. The two new methods are:

  • GetFormRegionManifest – returns the manifest XML as a string.
  • GetFormRegionIcon – returns an icon for this custom form region’s ribbon control, either as a byte-array or an IPictureDisp object.

If you want to provide the manifest and icon in this way, you also have to register the form region differently. For example, the old registry entry specified the path to the manifest:

[HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook\FormRegions\IPM.Task]

"TaskFormRegion"="%USERPROFILE%\\My Documents\\Visual Studio 2005\\Projects\\FormRegionWalkthrough\\FormRegionAddIn\\FormRegionAddIn\\Manifest.xml"

The new registry entry simply specifies an “=” followed by the ProgId of your add-in::

[HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook\FormRegions\IPM.Task]

"TaskFormRegion"="=FormRegionAddIn"

Also, the form region manifest itself needs to be changed. Many of the entries are no longer required. If you provide your manifest via the GetFormRegionManifest method, then the <name>, <layoutFile> and <addin> elements are ignored. There’s also a new element <icons>, where you can specify the word “addin” for each child <icon> element if you want Outlook to call GetFormRegionIcon for that icon.

Here’s what the updated version should look like. I’ve left the unused entries in as comments so you can see the differences. I’ve also put all the possible icon entries in as comments. This is a ‘separate’ form region, and for this form region style only the page icon is used, so that’s the only icon element that is not a comment:

<?xml version="1.0" encoding="utf-8"?>

<FormRegion xmlns="https://schemas.microsoft.com/office/outlook/12/formregion.xsd">

  <!--<name>TaskFormRegion</name>

  <title>Contoso</title>-->

  <formRegionType>separate</formRegionType>

  <formRegionName>Contoso</formRegionName>

  <showInspectorCompose>true</showInspectorCompose>

  <showInspectorRead>true</showInspectorRead>

  <showReadingPane>false</showReadingPane>

  <!--<hidden>true</hidden>

  <addin>FormRegionAddIn</addin>

  <version>1.0</version>-->

  <icons>

    <!--<default>addin</default>

    <unread>addin</unread>

    <read>addin</read>

    <replied>addin</replied>

    <forwarded>addin</forwarded>

    <unsent>addin</unsent>

    <submitted>addin</submitted>

    <signed>addin</signed>

    <encrypted>addin</encrypted>

    <window>addin</window>

    <recurring>addin</recurring>-->

    <page>addin</page>

  </icons>

</FormRegion>

Next, add this manifest XML as a resource to the project. If you’re basing this on the documented walkthrough, you’ll have two resources with the same base filename (that is, the TaskFormRegion.xml and TaskFormRegion.ofs, which will be named TaskFormRegion and TaskFormRegion1). To avoid confusion, you could rename the resources, to for example TaskFormRegionXML and TaskFormRegionOFS. If you do this, you’ll need to change the GetFormRegionStorage method accordingly:

public object GetFormRegionStorage(string FormRegionName, object Item, int LCID,

    Outlook.OlFormRegionMode FormRegionMode, Outlook.OlFormRegionSize FormRegionSize)

{

    Application.DoEvents();

    switch (FormRegionName)

    {

        case "TaskFormRegion":

            return Properties.Resources.TaskFormRegionOFS;

        default:

            return null;

    }

}

Then, you can implement the GetFormRegionManifest method very simply, like so:

public object GetFormRegionManifest(string FormRegionName, int LCID)

{

    return Properties.Resources.TaskFormRegionXML;

}

Now for the icon. Choose any suitable icon file, and add it as a resource to the project. Also add a helper class to convert the Icon type to the IPictureDisp type:

internal class PictureConverter : System.Windows.Forms.AxHost

{

    private PictureConverter() : base("") { }

    static public stdole.IPictureDisp IconToPictureDisp(System.Drawing.Icon icon)

    {

        return (stdole.IPictureDisp)GetIPictureDispFromPicture(icon.ToBitmap());

    }

}

Then, you can implement the second new FormRegionStartup method, GetFormRegionIcon:

public object GetFormRegionIcon(string FormRegionName, int LCID, Outlook.OlFormRegionIcon Icon)

{

    object icon = null;

    switch (Icon)

    {

        case Outlook.OlFormRegionIcon.olFormRegionIconPage:

            icon = PictureConverter.IconToPictureDisp(Properties.Resources.page);

        break;

    }

    return icon;

}

That’s it, build and test..

Comments

  • Anonymous
    November 28, 2006
    In my last post , I considered the final state of the FormRegionStartup interface, with the 2 new methods
  • Anonymous
    July 23, 2007
    Hi Andrew,I really appreciated to find your special version using the GetFormRegionManifest method !Although I tried several times your code, I did not find the way to make your sample working. In fact, my problems start as Outlook looks for FormRegion manifests in the registry. I deduce that it finds my key AssoContactForm="=MyAddin.Connect" that refers to the ProgID of the entry class of my add-in.Never the process enters the condition on the Guid of the FormRegion in the overrided RequestService method.I would like to add that the standard method (with the path of the manifest in the registry key) work almost good.The msdn library (http://msdn2.microsoft.com/en-us/library/bb206787.aspx) explaining the decisional mecanism of Outlook concerning the access to the manifest was helpful too!I don't really know what to try now...It would be grateful if you (or anyone !!) gave me some ways where to look for a resolution... Don't hesitate to reply if you would some more information about my case.Thank you,Romain
  • Anonymous
    January 15, 2008
    [UPDATE 2008-01-16: Today I finally got some time to verify that the GetFormRegionManifest method gets