Customizing the 2007 Office Fluent User Interface Using Visual Studio 2005 Tools for the Office System SE (Part 2 of 2)
Summary: This is the second in a two-part series of articles that shows you how to use Microsoft Visual Studio 2005 Tools for the 2007 Microsoft Office system to extend the user interface in solutions you build by using Microsoft Office applications such as Word, Excel, and Outlook. You will learn how to customize the Office Fluent Ribbon, create and display your own custom task panes, and how to create custom forms in Outlook. (18 printed pages)
Ken Getz, MCW Technologies, LLC
Jan Fransen, MCW Technologies, LLC
December 2007
Applies to:: Microsoft Visual Studio 2005 Tools Second Edition for the 2007 Microsoft Office System, Microsoft Office Excel 2007, Microsoft Office Outlook 2007, Microsoft Office Word 2007
Contents
Extending Outlook with Custom Form Regions
Anatomy of a Custom Form Region Solution
How Outlook 2007 Loads Your Form
Building a Simple Custom Form Region
Adding a Ribbon to a Form Region Add-in
Conclusion
Additional Resources
About the Authors
Extending Outlook with Custom Form Regions
The 2007 Microsoft Office system provides a wealth of interface enhancements that make common tasks easier and that allow users to be more productive. Microsoft Office Outlook has supported custom forms for a long time—that is, user-defined forms that replace the forms Outlook uses to display items such as contacts or e-mail messages. Developing applications using Outlook custom forms was possible, but complicated and very different from other types of Office development. Any code had to be written in Microsoft VBScript, only the Click event was supported for controls, forms could not be used with the Reading pane, and robust deployment was notoriously difficult.
With Microsoft Office Outlook 2007, Microsoft has changed the way developers can create form-based solutions and has made Office Outlook 2007 development more consistent with development in other Microsoft Office products. With the new custom form region feature, you can choose to replace a standard form entirely or complement the existing form. You can choose to have the form region adjoin the standard form on the same screen, or display it as its own page. Although you are not strictly required to write any code for your custom form region, most solutions are best developed as Outlook 2007 add-ins written by using Microsoft Visual Studio 2005 Tools Second Edition for the 2007 Microsoft Office System (Visual Studio 2005 Tools for Office SE).
Anatomy of a Custom Form Region Solution
To create a custom form add-in solution, you need to create four items:
A custom form region.
A Visual Studio 2005 Tools for Office SE add-in for Outlook 2007 that implements the FormRegionStartup interface. The custom form region can be embedded in the add-in solution. The add-in might also contain code to initialize the form region’s controls and respond to user events.
An XML manifest that tells Outlook 2007 about the form region and how to display it.
An entry in the Windows registry that tells Outlook 2007 where to find the XML manifest.
When you create Office Word 2007, Office Excel 2007, or Office PowerPoint 2007 add-ins that use forms, you create those forms as Windows Forms in Visual Studio. In Outlook 2007, custom form regions are still created in Outlook by using the Outlook Form Designer. The designer is similar to the original Outlook Form Designer, but it supports a much richer set of controls. Controls like Business Card and Contact Photo are built-in; you can also use any ActiveX control you like. Controls support a range of events in addition to the Click event.
After you create the form region in Outlook, save it as an .ofs file. Then you can move to Visual Studio 2005 Tools for Office SE to create the add-in that controls your new form region. Although the code you use to fill and add functionality to the custom form region differs from one solution to the next, the steps you use to build a custom form region and an associated add-in are the same, regardless of the complexity of the solution.
How Outlook 2007 Loads Your Form
After you create the form, write and install the add-in, create the XML manifest, and add the registry key, Outlook 2007 knows how to load your custom form region. To determine what to load and when to load it, Outlook 2007 follows these steps.
To load your Outlook 2007 custom form region, follow these guidelines.
When the user opens or creates an item, or displays an item in the Reading pane, Outlook 2007 checks the registry for a key that corresponds to the item type (Contact, Task, and so on.).
The registry key points to the add-in, using the ProgID of the add-in.
Outlook 2007 calls the GetFormRegionManifest method of the add-in to get the XML manifest. Outlook 2007 reads the XML manifest to determine when to use the form (Compose, Read, or Preview), how to display the form (adjoining the first page of the standard form or as a separate page), and what add-in to use to find and work with the form.
Note You can also use the XML manifest to specify that Outlook 2007 use icons on the Office Fluent Ribbon control of the custom form region. This example does not use icons on the Office Fluent Ribbon.
Outlook 2007 calls the RequestService method of the add-in, sending the FormRegionStartup GUID.
The RequestService method directs Outlook 2007 to the class that you created, to implement the FormRegionStartup interface.
A method of the class returns the custom form region to Outlook 2007.
Outlook 2007 loads the item, incorporating the form region that you specified.
Building a Simple Custom Form Region
The code you write to populate the form region could range from simple to very complex. The following is a simple example that shows you how to customize the Contact form so that the user sees some of the Personal fields (Birthday, Anniversary, Spouse/Partner, and Children) in a separate region while looking at the main page of the Contact form, as shown in Figure 1.
Figure 1. The solution adds an adjoining form region to the main page of the default Contact form
Designing a Custom Form Region
To create a new custom form region for the Contacts form, follow these steps.
To create a new custom form region
Start Outlook 2007.
On the Tools menu, point to Forms and then click Design a Form.
In the Design Form dialog box, select Contact and click Open. You see the Contact form in Design view, as shown in Figure 2.
Figure 2. You can use the designer to edit the default form or add custom form regions
In the Design group on the Office Fluent Ribbon, click Form Region and click New Form Region, as shown in Figure 3. Add a new, blank page to the form.
Figure 3. Use the Form Region button to create a new form region
In the Tools group, click Field Chooser to display the Field Chooser tool if it is not already displayed.
In the Field Chooser, use the drop-down list box to change the field list to Personal fields.
Drag the Birthday, Anniversary, Spouse/Partner, and Children fields from the Field Chooser to the form, as shown in Figure 4.
Figure 4. Dragging fields from the Field Chooser creates text boxes on the form
Select the text box for the Birthday field.
In the Tools group on the Office Fluent Ribbon, click the Property Sheet icon to show the properties for the text box.
Change the name of the text box to OlkBirthday.
Click OK to close the text box.
Use the Properties dialog box to change the names of the Anniversary, Spouse/Partner, and Children text boxes to OlkAnniversary, OlkSpousePartner, and OlkChildren.
In the Design group on the Office Fluent Ribbon, click Form Region and click Save Form Region As.
Save the form region to your Visual Studio 2005 Projects folder, naming it PersonalFieldsRegion.ofs.
Close the designer without saving changes. Close Outlook 2007.
Using Visual Studio 2005 Tools for Office Second Edition to Create an Outlook 2007 Add-in
Now that you have created a form region, you can build the Outlook 2007 add-in that loads it. To build the add-in, follow these steps.
To build the Outlook 2007 add-in
Open Visual Studio 2005.
On the File menu, click New Project.
In the New Project dialog box, browse to the Office node and then to the 2007 Add-ins branch under your preferred language.
Select the Outlook Add-in template.
Name the add-in PersonalFields.
When you write code to display the custom form region, you can refer to the file you saved by using its path and file name. You will find it easier, though, to add the file to the project as an embedded resource.
To add the form region file to the add-in solution as an embedded resource, right-click the PersonalFields project in Solution Explorer and click Properties.
Select the Resources page.
Click the Add Resource dropdown arrow and click Add Existing File.
Select the PersonalFieldRegion.ofs file that you created in Outlook 2007 and click Open. The PersonalFieldRegion file is now an embedded resource, as shown in Figure 5.
Figure 5. An embedded resource is automatically included in your compiled project
Add a new class to interact with Outlook 2007 and the form region by right-clicking the PersonalFields project, pointing to Add, and then clicking Class.
Name the new class FormRegionHelper and click Add.
Most form region add-ins interact with the controls on the form region, so you need to add a reference to the UserForm interop assembly, Microsoft.Vbe.Interop.Forms.
Right-click the PersonalFields project and click Add Reference.
In the Add Reference dialog box’s .NET tab, select Microsoft.Vbe.Interop.Forms and click OK.
To make the class visible to COM, you need to add the ComVisible attribute, which is available through the System.Runtime.InteropServices namespace. Therefore, you should declare that namespace at the top of the class. You also need to declare the Outlook PIA namespace so that you can implement the Outlook FormRegionHelper interface. Many solutions require at least the occasional message box to provide the user with information, so the example includes a namespace declaration statement for Windows Forms as well.
At the top of the class, add the necessary namespace statements.
Imports System.Runtime.InteropServices Imports Microsoft.Vbe.Interop.Forms Imports Outlook = Microsoft.Office.Interop.Outlook Imports System.Windows.Forms
using System.Runtime.InteropServices; using Microsoft.Vbe.Interop.Forms; using Outlook = Microsoft.Office.Interop.Outlook; using System.Windows.Forms;
To interact with COM, your class must be visible to COM, include a GUID and a ProgID, and specify an AutoDual class interface. To set those attributes, add them to the class declaration.
<ComVisible(True), _ Guid("B3433DFA-BC0F-413b-82DC-53BD11F8D305"), _ ProgId("PersonalFields.FormRegionHelper"), _ ClassInterface(ClassInterfaceType.AutoDual)> _ Public Class FormRegionHelper
[ComVisible(true), Guid("58B93C55-81AA-4c6d-90C6-9A323D55AA7A"), ProgId("PersonalFields.FormRegionHelper"), ClassInterface(ClassInterfaceType.AutoDual)] class FormRegionHelper {
Note You can generate a GUID with the Create GUID dialog box, available on the Tools menu or by running the guidgen utility in the Visual Studio .NET Command Prompt window.
Add code to the class declaration to implement the FormRegionStartup interface.
<ComVisible(True), _ Guid("B3433DFA-BC0F-413b-82DC-53BD11F8D305"), _ ProgId("PersonalFields.FormRegionHelper"), _ ClassInterface(ClassInterfaceType.AutoDual)> _ Public Class FormRegionHelper Implements Outlook.FormRegionStartup
[ComVisible(true), Guid("58B93C55-81AA-4c6d-90C6-9A323D55AA7A"), ProgId("PersonalFields.FormRegionHelper"), ClassInterface(ClassInterfaceType.AutoDual)] class FormRegionHelper : Outlook.FormRegionStartup {
Outlook calls the GetFormRegionStorage method to determine what custom form region to open, and calls the BeforeFormRegionShow method before displaying the custom form region. If you are using Visual Basic, Visual Studio automatically generates the BeforeFormRegionShow and GetFormRegionStorage procedures when you press ENTER. If you are using C#, use the smart tag to fully implement the interface and create the methods, as shown in Figure 6.
Figure 6. Implement the Outlook.FormRegionStartup interface
Add code to GetFormRegionStorage to return the embedded form region resource.
Public Function GetFormRegionStorage( _ ByVal FormRegionName As String, _ ByVal Item As Object, _ ByVal LCID As Integer, _ ByVal FormRegionMode As Outlook.OlFormRegionMode, _ ByVal FormRegionSize As Outlook.OlFormRegionSize) As Object _ Implements Outlook._FormRegionStartup.GetFormRegionStorage Select Case FormRegionName Case "PersonalFieldsRegion" Dim ofsBytes As Byte() ofsBytes = My.Resources.PersonalFieldsRegion Return ofsBytes Case Else Return Nothing End Select End Function
public object GetFormRegionStorage(string FormRegionName, object Item, int LCID, Microsoft.Office.Interop.Outlook.OlFormRegionMode FormRegionMode, Microsoft.Office.Interop.Outlook.OlFormRegionSize FormRegionSize) { switch (FormRegionName) { case "PersonalFieldsRegion": byte[] ofsBytes = Properties.Resources.PersonalFieldsRegion; return ofsBytes; default: return null; } }
Note Outlook 2007 uses the Windows registry entry, described later in the example, to determine the value of FormRegionName.
When Outlook 2007 needs information about the custom form region, it calls the RequestService method of the add-in. You need to create this method in the ThisAddin class as an override to the RequestService virtual method of the Application class.
Open the ThisAddIn class in the ThisAddIn.vb file and add a variable for the FormRegionHelper class and the new RequestService method.
Private formRegionHelper As FormRegionHelper Protected Overrides Function RequestService( _ ByVal serviceGuid As System.Guid) As Object If serviceGuid = GetType(Outlook.FormRegionStartup).GUID Then If formRegionHelper Is Nothing Then formRegionHelper = New FormRegionHelper() End If Return formRegionHelper End If Return MyBase.RequestService(serviceGuid) End Function
private FormRegionHelper formRegionHelper; protected override object RequestService(Guid serviceGuid) { if (serviceGuid == typeof(Outlook.FormRegionStartup).GUID) { if (formRegionHelper == null) { formRegionHelper = new FormRegionHelper(); } return formRegionHelper; } return base.RequestService(serviceGuid); }
Creating a Form Region Manifest in XML
For each Outlook 2007 form region you create, you need a corresponding manifest that describes how the form region should look and act and that tells Outlook 2007 what add-in to use to get the form region and run its code. To create a form region manifest for the solution, follow these steps.
To create a form region manifest
In Visual Studio, right-click the PersonalFields project in Solution Explorer, point to Add, and then click New Item.
In the Add New Item dialog box, select XML File and name the new file PersonalFields.xml.
Click Add.
Specify how you want Outlook 2007 to display the custom form. For this example, the custom form adjoins the main Contact page. You can also specify a name for the form region. For an adjoining region like this one, Outlook 2007 uses the name you specify in the <formRegionName> element as the title of the region. Finally, you should specify the contexts in which Outlook 2007 should display the form: Compose, Read, or Preview. For a full description of all valid elements of the FormRegion node, see 2007 Office System: XML Schema Reference.
For this example, add the following XML document to the new XML file.
<?xml version="1.0" encoding="utf-8" ?> <FormRegion xmlns="http://schemas.microsoft.com/office/outlook/12/formregion.xsd"> <formRegionName>Personal Fields</formRegionName> <formRegionType>adjoining</formRegionType> <showCompose>true</showCompose> <showRead>true</showRead> <showPreview>false</showPreview> <icons> <default>addin</default> </icons> </FormRegion>
Save the XML file.
Right-click the PersonalFields project in Solution Explorer and click Properties.
Select the Resources page.
In Solution Explorer, select PersonalFields.xml and then drag and drop it into the Resources window.
Before Outlook 2007 can load your custom form region, it calls the GetFormRegionManifest method to find the XML manifest. Follow the steps below to add the code that returns the XML manifest.
In the FormRegionHelper class, add code to the GetFormRegionManifest method.
Public Function GetFormRegionManifest( _ ByVal FormRegionName As String, ByVal LCID As Integer) _ As Object _ Implements Microsoft.Office.Interop.Outlook._FormRegionStartup. _ GetFormRegionManifest Return My.Resources.PersonalFields End Function
public object GetFormRegionManifest(string FormRegionName, int LCID) { if (FormRegionName == "PersonalFieldsRegion") { return Properties.Resources.PersonalFields; } return null; }
From the Build menu, select Build Solution.
Telling Outlook 2007 about Your Solution by using the Windows Registry
Finally, you must indicate to Outlook 2007 that you have a custom form region for the Contact form and specify the add-in you created. To manually add a registry key, follow these steps.
To add a registry key for the add-in
Click the Start button, and click Run.
In the Run dialog box, type regedit and press ENTER.
In the Registry Editor, browse to HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook.
If there is no FormRegions key, create one by right-clicking the Outlook key, point to New, and then clicking Key. Name the new key FormRegions.
Within FormRegions, if there is no IPM.Contact key, add one by right-clicking the FormRegions key, pointing to New, and then clicking Key. Name the new key IPM.Contact.
Within IPM.Contact, add a new string value by right-clicking the IPM.Contact key, pointing to New, and then clicking String value. Name the new string value PersonalFieldsRegion.
Double-click the PersonalFieldsRegion string and use the Edit String dialog box to type an equals sign and the ProgID of the add-in:
=PersonalFields
Close the Registry Editor.
Testing the Outlook Solution
To test your solution, follow these steps.
To test the Outlook solution
In Visual Studio 2005, press CTRL+F5 to run the add-in. Visual Studio 2005 launches Outlook 2007.
In Outlook 2007, double-click any contact to open the Contact form in Read context. You see the Contact form with the new Personal Fields region, as shown previously in Figure 1.
Note If you want to deploy the add-in to another computer, you need to perform a few more steps to customize the Setup project for the add-in. This article does not cover deployment; for information about how to deploy a custom form region solution for Outlook 2007, see Additional Resources at the end of this article.
Adding a Ribbon to a Form Region Add-in
As you just saw, Outlook 2007 calls the RequestService method for an add-in to get information about the custom form region. As described in the section on the Office Fluent Ribbon, the applications in the 2007 Office system also use the RequestService method of an add-in to get information about the Office Fluent Ribbon. If your solution uses both the Office Fluent Ribbon and custom forms, you need a single RequestService method that handles both.
Suppose that you want to provide an Office Fluent Ribbon through the custom form region add-in that you just created. You add an Office Fluent Ribbon item to the add-in, just as you would in any add-in. But rather than uncommenting the RequestService method provided in the Ribbon class, you add code to the existing RequestService method in the ThisAddIn class to handle the Office Fluent Ribbon.
To see how an Office Fluent Ribbon and a custom form region coexist, the following exercise adds an Office Fluent Ribbon customization to the custom form region add-in. In this example, the function of the single button of the Office Fluent Ribbon is simple: It displays the contact’s birthday in a message box.
To add a button to the Office Fluent Ribbon when the Contact form is open, follow these steps.
To add a button to the Office Fluent Ribbon
Close Outlook 2007 if it is still open.
In Visual Studio 2005, right-click the PersonalFields project in Solution Explorer, point to Add, and then click New Item.
In the Add New Item dialog box, select the Ribbon support template.
Name the new item ContactRibbon.vb (or ContactRibbon.cs).
Click Add.
Double-click ContactRibbon.xml in Solution Explorer to open the XML file.
Edit the ContactRibbon.xml file to display a new button in the Show group of the Contact Ribbon:
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="OnLoad"> <ribbon> <tabs> <tab idMso="TabContact"> <group id="MyGroup" label="Personal" insertAfterMso="GroupShow"> <button id="BirthdayButton" size="large" label="Birthday" screentip="Birthday" onAction="OnBirthdayButton" imageMso="HappyFace" /> </group> </tab> </tabs> </ribbon> </customUI>
Save the ContactRibbon.xml file.
Add the ContactRibbon.xml file to the project resources by right-clicking the PersonalFields project in Solution Explorer and clicking Properties.
Click the Resources tab.
Drag ContactRibbon.xml from Solution Explorer to the surface of the Resources page.
In the ContactRibbon class in the ContactRibbon.vb file, change the GetCustomUI method to return the strongly-typed resource only if the user is inspecting a contact:
Public Function GetCustomUI(ByVal ribbonID As String) As String _ Implements Office.IRibbonExtensibility.GetCustomUI Dim xmlMarkup As String = String.Empty If ribbonID = "Microsoft.Outlook.Contact" Then xmlMarkup = My.Resources.ContactRibbon End If Return xmlMarkup End Function
public string GetCustomUI(string ribbonID) { string xmlMarkup = String.Empty; if (ribbonID == "Microsoft.Outlook.Contact") { xmlMarkup = Properties.Resources.ContactRibbon; } return xmlMarkup; }
Delete the GetResourceText method, located in the Helpers region of the ContactRibbon class.
Delete the sample OnToggleButton1 method, located in the Ribbon Callbacks region of the ContactRibbon class.
The callback method of the new button requires information from the current Outlook contact, so add a statement at the top of the class to declare the Outlook PIA namespace:
Imports Outlook = Microsoft.Office.Interop.Outlook
using Outlook = Microsoft.Office.Interop.Outlook;
Add an OnBirthdayButton method to show the contact’s birthday:
Public Sub OnBirthdayButton(ByVal control As Office.IRibbonControl) Dim inspector As Outlook.Inspector = control.Context Dim contact As Outlook.ContactItem = inspector.CurrentItem If contact.Birthday = #1/1/4501# Then MessageBox.Show("No birthday has been specified.") Else MessageBox.Show(contact.Birthday) End If End Sub
public void OnBirthdayButton(Office.IRibbonControl control) { Outlook.Inspector inspector = (Outlook.Inspector)control.Context ; Outlook.ContactItem contact = (Outlook.ContactItem)inspector.CurrentItem; DateTime birthday = contact.Birthday; if (DateTime.Compare(birthday, new DateTime(4501,1,1)) == 0) { MessageBox.Show("No birthday has been specified."); } else { MessageBox.Show(birthday.ToString("d")); } return; }
Open the ThisAddIn class in the ThisAddIn.vb file.
Add a private variable for the Ribbon at the top of the class:
public class ThisAddIn Private formRegionHelper As FormRegionHelper Private ribbon As ContactRibbon
public partial class ThisAddIn { private ContactRibbon ribbon; private FormRegionHelper formRegionHelper;
Edit the RequestService method to check for the Ribbon extensibility GUID:
Protected Overrides Function RequestService( _ ByVal serviceGuid As System.Guid) As Object Select Case serviceGuid Case GetType(Outlook.FormRegionStartup).GUID If formRegionHelper Is Nothing Then formRegionHelper = New FormRegionHelper() End If Return formRegionHelper Case GetType(Office.IRibbonExtensibility).GUID If ribbon Is Nothing Then ribbon = New ContactRibbon() End If Return ribbon End Select Return MyBase.RequestService(serviceGuid) End Function
protected override object RequestService(Guid serviceGuid) { if (serviceGuid == typeof(Outlook.FormRegionStartup).GUID) { if (formRegionHelper == null) { formRegionHelper = new FormRegionHelper(); } return formRegionHelper; } else { if (serviceGuid == typeof(Office.IRibbonExtensibility).GUID) { { if (ribbon == null) { ribbon = new ContactRibbon(); return ribbon; } } } } return base.RequestService(serviceGuid); }
Note You can copy code from the commented-out RequestService method in the ContactRibbon class.
Press CTRL+F5 to run the add-in within Outlook 2007.
When Outlook 2007 opens, move to Contacts and double-click any contact to open the item. You see the new button on the Office Fluent Ribbon, as show in Figure 7.
Figure 7. The new button is added to the Contact Ribbon, next to the Show group
Click the Birthday button. A message box appears, displaying the contact’s birthday. If you haven’t entered a birthday for the contact you chose, a message box reminds you that no birthday is entered.
Conclusion
In this article, you learned how to use Visual Studio 2005 Tools for Office Second Edition to create add-ins for those 2007 Office system products that support them. You can use the powerful Windows Forms tool that are available in Visual Studio 2005 to design custom task panes for both document-based and application-based solutions throughout most of the 2007 Office system. Outlook 2007 provides custom form regions to more easily enhance the forms that your users are accustomed to in Outlook. The new 2007 Office system products allow you to use XML markup to customize the ribbon wherever it is supported.
Additional Resources
You can find more information in the technical articles and Visual How To at the following locations:
Customizing the Ribbon in Outlook 2007 Using Visual Studio 2005 Tools for the Office System SE
Customizing the 2007 Office Fluent Ribbon for Developers (Part 1 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 2 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 3 of 3)
About the Authors
Ken Getz is a developer, writer, and trainer, working as a senior consultant with MCW Technologies, LLC, a Microsoft Solution Provider. Ken co-authored AppDev's C#, ASP.NET, Visual Basic, and ADO.NET courseware. He has co-authored several technical books for developers, including the best-selling ASP.NET Developer's Jumpstart, the Access Developer's Handbook series, and the VBA Developer's Handbook series. Ken is a technical editor for Advisor Publications' VB.NET Technical Journal, and he is a columnist for both MSDN Magazine and CoDe Magazine. Ken speaks regularly at a large number of industry events, including Advisor Media's Advisor Live events, FTP's VSLive, and Microsoft Tech·Ed.
Jan Fransen is a writer, trainer, and developer specializing in Microsoft products. Jan authored AppDev’s Microsoft Visual Studio Tools for Office, Microsoft Office, and Visual Basic for Applications courseware, and co-authored AppDev’s .NET Framework 2.0 courseware. Jan has contributed to books about Microsoft Office, written white papers for publication on MSDN, and created samples designed to help developers get up to speed quickly on new Microsoft products and features.