Create Office 2010 - 2000 plugins / add-ins in
Visual Studio .NET: VB, C#, C++ - Developer's Guide

Add-in Express™ Regions
for Microsoft® Outlook® and VSTO

Add-in Express Home >

Programming with Advanced Regions

You can use Add-in Express Regions for Outlook and directly within your VSTO 2008 or 2010 projects. Create an Outlook add-in project in VSTO and add an Add-in Express Advanced Outlook Region class to the project. Doing this starts the Add New Region wizard:

Adding an Add-in Express Advanced Outlook Region class to the project

The wizard adds a form region class to your project and allows specifying the following settings of your region:

  • To show the form in the Explorer and / or Inspector windows
  • In which position to show the form
  • To show the form expanded or minimized
  • To show the form for particular Outlook item types and / or folders
  • Some others

After the form is added, add a button and label onto the form. The controls in the sample are named Button1 and Label1.

Is it Inspector or Explorer?

Add an event handler for the Load event of the form and write the following code:

Public Class ADXOlForm1
	...
	Private Sub ADXOlForm1_Load(ByVal sender As System.Object, _
								ByVal e As System.EventArgs) Handles MyBase.Load
		If Me.InspectorObj Is Nothing Then Me.Button1.Visible = False
		If Me.ExplorerObj Is Nothing Then Me.Label1.Visible = False
	End Sub

The code above demonstrates the base principle:

  • if ADXOlForm.InspectorObj returns a value other than Nothing (null in C#), then the form is shown in an Outlook Inspector window;
  • similarly, if ADXOlForm.ExplorerObj returns a value other than Nothing (null in C#), then the form is shown in an Outlook Explorer window.

InspectorObj and ExplorerObj properties return COM objects that you must never release in your code because their state is crucial for the functionality of your advanced region. These properties will be released automatically when your form is removed from its region. This may occur several times during the lifetime of a given form instance because the manager may remove your form from a given region and then embed the form to the same region in order to comply with the Outlook windowing.

Accessing ThisAddIn from the form

We suggest adding a Shared (static in C#) member in ThisAddIn. In this sample, we use the code below:


			Public Class ThisAddIn

    Public Shared AddinInstance As ThisAddIn

    Private Sub ThisAddIn_Startup() Handles Me.Startup

        ' >auto-generated<
        ' Add-in Express Regions generated code - do not modify
        Me.FormsManager = AddinExpress.OL.ADXOlFormsManager.CurrentInstance
        Me.FormsManager.Initialize(Me)
        ' >/auto-generated<

        ThisAddIn.AddinInstance = Me
    End Sub
...  
End Class
            

The use of AddinInstance is demonstrated below.

Accessing the Outlook Object Model

Add the following to the Click event handler of the button:


			Imports System.Windows.Forms

Public Class ADXOlForm1
...  
    Private Sub Button1_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) Handles Button1.Click
        MessageBox.Show(ThisAddIn.AddinInstance. _
                        GetSubject(TryCast(Me.InspectorObj, Outlook.Inspector)))
    End Sub

			

And in ThisAddIn, add methods that deal with the Outlook object model:


			Imports System.Runtime.InteropServices

Public Class ThisAddIn
...
    Public Function GetSubject(ByVal anInspector As Outlook.Inspector) As String

        Dim result As String = ""
        If anInspector Is Nothing Then
            Throw New Exception("The parameter must be an Outlook.Inspector.")
            result = "undefined"
        Else
            Dim item As Object = anInspector.CurrentItem
            result = GetSubject(item)
            Me.ReleaseComObject(item)
            item = Nothing
        End If
        ' The caller is responsible for releasing anInspector (a COM object)
        Return result
    End Function

    Private Function GetSubject(ByVal OutlookItem As Object) As String
        Dim result As String = ""
        If Not TypeOf OutlookItem Is Outlook.MailItem Then
            result = "This is not an e-mail."
        Else
            Dim mail As Outlook.MailItem = TryCast(OutlookItem, Outlook.MailItem)
            Try
                result = mail.Subject
                If result = "" Then result = "(no subject)"
            Catch ex As Exception
                result = "Exception: " + ex.Message
            End Try
        End If
        ' The caller is responsible for releasing OutlookItem (a COM object)
        Return result
    End Function
            

Note that the COM object standing for the Outlook Inspector is not released in the code above; that's because that COM object is controlled by the forms manager and it must not be released in your code (see below).

Releasing COM objects - a must in Outlook add-ins

A comprehensive review of typical problems (and solutions) related to releasing COM objects in Office add-ins is given in an article published on the Add-in Express technical blog - When to release COM objects in Office add-ins?

Below are some useful tips.

Pay attention that Inspector.CurrentItem returns an Object (with an underlying RCW pointing to the COM object) and passing the Object to another method as well as casting it to Outlook.MailItem doesn't produce new COM objects (doesn't increase the reference counter).

Passing Nothing (null in C#) to ReleaseComObject produces an exception. Passing a non-COM object to ReleaseComObject produces an exception, too. These situations are handled by the method you add to ThisAddIn:

Public Class ThisAddIn
...
Private Sub ReleaseComObject(ByVal obj As Object)
	If obj IsNot Nothing Then
		If Marshal.IsComObject(obj) Then
			Marshal.ReleaseComObject(obj)
		End If
	End If
End Sub

			

You can also get the "COM object that has been separated from its underlying RCW cannot be used" exception if you pass a variable to ReleaseComObject and then use the variable in your code. We recommend assigning Nothing (null in C#) to all released variables.

The functionality provided by Add-in Express Regions for Outlook and VSTO is based on the combined use of the Outlook windowing and features provided by the Outlook object model. These two areas are essentially different and keeping objects from these areas in sync requires significant efforts. Some difficulties are impossible to overcome. One of them is born by the need to control the state of COM objects provided by in properties and events of Add-in Express Regions: releasing any of such objects may lead to a run-time exception.

Do not release any COM objects you acquire in the properties and events of ADXOlFormsManager and ADXOlForm. On the contrary, release every COM object you create in your code.

Dealing with Outlook events

Let's handle the SelectionChange event provided by the Outlook.Explorer object.

Public Class ThisAddIn

    Private WithEvents theExplorer As Outlook.Explorer
	...
    Private Sub ThisAddIn_Startup() Handles Me.Startup
	...
        theExplorer = Me.Application.ActiveExplorer()
	...
    End Sub

    Private Sub DoExplorerSelectionChange() Handles theExplorer.SelectionChange
        Dim result As String = GetSubject(theExplorer)
        'TODO: show the subject on the form
    End Sub

    Public Function GetSubject(anExplorer As Outlook.Explorer) As String
        Dim selection As Outlook.Selection = Nothing
        Try
            selection = anExplorer.Selection
        Catch
            ' Skip an exception that occurs if the current 
            ' Outlook folder is a top-level one
        End Try

        Dim result As String = ""

        If selection Is Nothing Then
            result = "This is a top-level folder. It contains no items."
        Else
            Try
                If selection.Count = 0 Then
                    result = "The current folder contains no items."
                Else
                    Dim item As Object = selection.Item(1)
                    result = GetSubject(item)
                    Me.ReleaseComObject(item)
                    item = Nothing
                End If
            Finally
                Me.ReleaseComObject(selection)
                selection = Nothing
            End Try
        End If
        Return result
    End Function

    Private Sub DoExplorerClose() Handles theExplorer.Close
        Me.ReleaseComObject(theExplorer)
        theExplorer = Nothing
    End Sub
	...
End Class
                

The DoExplorerClose method demonstrates how you disconnect from events provided by a COM object.

Accessing the form from ThisAddIn

You get a collection item and call the GetCurrentForm method. That method provides a parameter the possible values of which address to the Visible and Active properties of ADXOlForm.

The Visible property of a form region instance is true when the instance is embedded into a window region (as specified by the visualization settings) regardless of the actual visibility of the instance.

The Active property of the form region instance is true when the instance is shown on top of all other instances in the same region.

The code is shown below:


				    Private Sub DoExplorerSelectionChange() Handles theExplorer.SelectionChange
        Dim result As String = GetSubject()
        Dim form As ADXOlForm1 = _
            TryCast(FormsManager.Items(0).GetCurrentForm( _
                    AddinExpress.OL.EmbeddedFormStates.Visible), ADXOlForm1)
        If form IsNot Nothing Then form.SelectedItemSubject = result
    End Sub

				 

The code refers to the SelectedItemSubject property defined in ADXOlForm1; the code of the property is omitted for brevity - it just assigns the string to Label1.Text.

See Also