Ty Anderson

How to create an Outlook task, appointment or note from an email

In the first installment of this series, Outlook 2010 addin development: customizing Ribbon & toolbar in a single plugin, we took the first step in building the Ty Actions Outlook Add-in. If you followed along, you have a beautiful custom Outlook ribbon and a custom a command bar that will impress your users… at least until they click a button. In this, part 2, of the series, we will correct this issue by writing some code. This code will fulfill the first two requirements for the add-in. If you don’t remember what they are, let’s review:

  1. Provide the capability to create a task, appointment, or note from an email.
  2. Extend the default “Create task” functionality to do more than Outlook does by default. I know, this is nice and vague but it will take a more definitive shape soon enough.
  3. Provide custom Outlook toolbars (ribbon or commandbar) for Explorer and Inspector windows.
  4. Support both Outlook 2007 and Outlook 2010.

We already completed #3 and #4. Apparently, we are working backwards. I guess I like to begin with the end in mind. Also, as I mentioned in Part 1 would probably happen, the requirements have changed to include what I’m calling the Contact Info form.

The idea of this Outlook custom form is to display contact info when you select an email in the Outlook Explorer window. As you move about the inbox and select different emails, the add-in will check your default Contacts folder for matching email address. If it finds a match, the add-in displays the Contact Info form. Otherwise, the form remains hidden. To keep our requirements list current, we’ll add the following:

5. Create a custom form to display the sender’s contact info from the currently selected email.

Alright. I’m feeling pretty good about our requirements and the fact that this will be a useful Outlook add-in. Let’s get to it then:

Creating an Outlook custom form: Contact info form

In the Ty Actions Visual Studio project, add a new Advanced Form Region. This project item template allows you to use a custom .NET Windows form to extend the Outlook UI. In our case, we will build a custom Outlook form region that displays inside the Explorer window… in the bottom of the preview pane.

You add the Advanced Form Regions in the same manner you add any new item to VS project. Form the VS menu, click Project | Add New Item…

Adding the Outlook Form template in Visual Studio

In the Add New Item dialog box, expand Add-in Express Items and select the Outlook node. There, you will find the ADX Outlook Form template. Be sure to name the form ContactInfo. After you click Add, Visual Studio will display the following warning:

For a custom form to work, add Outlook Forms Manager component to the Add-in Module

This message is our way of reminding you to add an Outlook Forms Manager component to the Add-in Module. We’ll take care of that in a moment. For now, click the OK button and we’ll complete the form design.

The ContactInfo form is ADXOlForm which inherits from Windows Forms. So, you can use any .NET controls (out-of-the-box from Visual Studio or 3rd Party controls) to design some killer Outlook user interfaces. Today’s sample add-in will not be killer but it will be functional.

Our Outook ContactInfo form has 10 labels used to display contact info. Building it might take five minutes… it’s plenty easy to do as you will discover by completing these steps.

  1. Add a Label control to the form and change these properties:
    • Text = Full Name:
    • TextAlign = TopRight
    • Bold = True
  2. Add a Label control to the form and change these properties:
    • Text = Title:
    • TextAlign = TopRight
    • Bold = True
  3. Add a Label control to the form and change these properties:
    • Text = Company:
    • TextAlign = TopRight
    • Bold = True
  4. Add a Label control to the form and change these properties:
    • Text = Business Phone:
    • TextAlign = TopRight
    • Bold = True
  5. Add a Label control to the form and change these properties:
    • Text = Mobile Phone:
    • TextAlign = TopRight
    • Bold = True
  6. Add a Label control to the form next to the Full Name label.
    • Name = lblFullName
    • Text = Full Name Goes Here
  7. Add a Label control to the form next to the Title label.
    • Name = lblTitle
    • Text = Title Goes Here
  8. Add a Label control to the form next to the Company label.
    • Name = lblCompany
    • Text = Company Name Goes Here
  9. Add a Label control to the form next to the Business Phone label.
    • Name = lblBusinessPhone
    • Text = Business Phone Goes Here
  10. Add a Label control to the form next to the Mobile Phone label.
    • Name = lblMobilePhone
    • Text = Mobile Phone Goes Here

Done correctly, our Outlook custom form looks like this:

Outlook custom form design

Add Outlook Forms Manager to control custom forms

The Outlook Forms Manager is an Add-in Express component that manages the instances of our ContactInfo advanced Outlook form region. Thanks to this component, we do not need to write code to track all Outlook windows, create new instances of our custom form, display them, etc. Nope… all we need to do is add our form to the Outlook Forms Manager’s collection and configure some properties.

Display the AddinModule in design view. Add and Outlook Forms Manager control by clicking its icon in the AddinModule’s toolbar (you can also right-click on the design surface and select it in the context menu). Now, select the newly added AdxOlFormsManager1 control. In the Properties window, find the Items property and click the ellipsis button to open the collection editor.

Configuring the properties of the Outlook custom form

Click the Add button to add a new item to the collection. Then configure the following properties:

  • Cached = OneInstanceForAllFolders
  • ExplorerItemTypes = Mail
  • ExplorerLayout = BottomReadingPane
  • FormClassName = TyActions.ContactInfo (or whatever you named your form)

Click the OK button and you’re done. Now, anytime we display the ContactInfo form, it will be visible in the bottom of the Outlook reading pane.

We are now ready to write code.

Coding for magic: writing business logic of Outlook add-in

To meet requirements #1 and #2, we need three custom methods. The methods are:

  • CreateLinkedItem : This method does the hard duty of creating an Outlook item. Either a task, appointment, or note.
  • AttachSelections: This method attaches the currently selected email into the body of the item created in CreateLinkedItem.
  • GetContactInfo: This method searches the default contacts folder for a contact with an email address that matches the currently selected email.

None of these are too complicated. But just in case, I explain each one as we go along.

A bit of code setup: class-level variables

Before we write the method, we need a few class-level variables. Open the AddinModule.vb file and display its Code View. Add the follow “private members” to the class. I recommend cutting and pasting.

#Region "Private Members"
  Private _ContactFullName As String
  Private _Title As String
  Private _Company As String
  Private _BusinessPhone As String
  Private _MobilePhone As String
  Private _ValidContact As Boolean
#End Region

These guys (the private members) are class properties that allow us to store contact info within the class. If ever I decide to let other objects access these values, we’ll implement property methods for them. For now, this works just fine.

Creating an Outlook task, appointment or note from a selected email

Outlook’s custom toolbar (ribbon and command bar) buttons call this method. The idea is to take the currently selected email and create an Outlook item. Add the following code to the AddinModule class.

VB.NET code example

Private Sub CreateLinkedItem(ByVal itemType As Outlook.OlItemType)
 
    Dim explorer As Outlook.Explorer = _
		DirectCast(OutlookApp.ActiveExplorer, Outlook.Explorer)
    Dim sel As Outlook.Selection = Nothing
    Try
      sel = explorer.Selection
    Catch
    End Try
 
    If sel IsNot Nothing Then
      If sel.Count > 0 Then
        Dim email As Outlook.MailItem = TryCast(sel.Item(1), Outlook.MailItem)
        If email IsNot Nothing Then
          Select Case itemType
            Case Outlook.OlItemType.olAppointmentItem
              Dim olItem As Outlook.AppointmentItem = _
				TryCast(OutlookApp.CreateItem(itemType), Outlook.AppointmentItem)
              olItem.Subject = "Appt: " & email.Subject
              olItem.Body = email.Body
              AttachSelections(olItem, sel)
              olItem.Display()
              Marshal.ReleaseComObject(olItem)
            Case Outlook.OlItemType.olTaskItem
              Dim olItem As Outlook.TaskItem = _
				TryCast(OutlookApp.CreateItem(itemType), Outlook.TaskItem)
              olItem.Subject = "Task: " & email.Subject
              olItem.Body = email.Body
              olItem.ContactNames = email.ReceivedByName
              AttachSelections(olItem, sel)
              olItem.Display()
              Marshal.ReleaseComObject(olItem)
            Case Outlook.OlItemType.olNoteItem
              Dim olItem As Outlook.NoteItem = _
				TryCast(OutlookApp.CreateItem(itemType), Outlook.NoteItem)
              olItem.Body = email.Subject & vbCrLf & email.Body
              olItem.Display()
              Marshal.ReleaseComObject(olItem)
          End Select
          Marshal.ReleaseComObject(email)
        End If
      End If
      Marshal.ReleaseComObject(sel)
    End If
    Marshal.ReleaseComObject(explorer)
  End Sub

The type of item is a parameter of the method. The code branches depending on the type specified using a Select statement. For Outlook appointment and task items, the code will use the email’s subject and body to fill the item’s same values. Also for these types, the method calls AttachSelections to embed the selected email into the new item.

For Outlook note items, the code combines the email subject and body. For notes, the subject property is read only. But this strategy will cause the email subject to become the note’s subject. Notes do not support embedded objects so we will not attempt to embed the source email. We’ll let it be.

Adding selected email items to a task or appointment

This method only receives love and attention from CreateLinkedItem. It requires an item and an Outlook Selection object as parameters. Add the following to the AddinModule class.

VB.NET code example

Private Sub AttachSelections(ByRef item As Object, ByRef sel As Outlook.Selection)
    Dim i As Integer
    Dim attachments As Outlook.Attachments = item.Attachments
 
    For i = 1 To sel.Count
      Dim itemToAttach As Object = sel.Item(i)
      attachments.Add(itemToAttach)
      Marshal.ReleaseComObject(itemToAttach)
    Next
    Marshal.ReleaseComObject(attachments)
  End Sub

When called, the first thing it does is count the number of items. It then loops and adds each item in the selection object’s Item collection to the passed Outlook item. That’s it and that’s all… for this method at least.

Searching for a contact item by an email address

This method accepts an email string as a parameter. It then gets to work rummaging around the user’s default contacts folder, looking for an Outlook contact with a matching email. If it finds one, it stores the info we want in the private members we added just a few minutes ago. It also returns True to let the calling method know it found a contact. If no contact is found, we set empty strings and return false. Here is the code to add to the AddinModule class.

VB.NET code sample

Friend Function GetContactInfo(ByVal email As String) As Boolean
	If String.IsNullOrEmpty(email) Then Return False
 
    Dim found As Boolean = False
    Dim ns As Outlook.NameSpace = OutlookApp.GetNamespace("MAPI")
    If ns IsNot Nothing Then
      Dim contactsFolder As Outlook.Folder = _
        DirectCast(ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts), _
			Outlook.Folder)
 
       If contactsFolder IsNot Nothing Then
        Dim contactItems As Outlook.Items = contactsFolder.Items
 
        If contactItems IsNot Nothing Then
          Dim contact As Outlook.ContactItem = TryCast(contactItems.Find(
              "[Email1Address] = '" & email.ToString &
              "' or [Email2Address] = '" & email.ToString &
              "' or [Email3Address] = '" & email.ToString & "'"), Outlook.ContactItem)
          If Not IsNothing(contact) Then
            _ContactFullName = contact.FullName.ToString
            _Title = contact.JobTitle
            _Company = contact.CompanyName
            _BusinessPhone = contact.BusinessTelephoneNumber
            _MobilePhone = contact.MobileTelephoneNumber
 
            found = True
            Marshal.ReleaseComObject(contact)
          Else
            _ContactFullName = ""
            _Title = ""
            _Company = ""
            _BusinessPhone = ""
            _MobilePhone = ""
 
            found = False
          End If
          Marshal.ReleaseComObject(contactItems)
        End If
        Marshal.ReleaseComObject(contactsFolder)
      End If
      Marshal.ReleaseComObject(ns)
    End If
    Return found
  End Function

The only real trick here is to call the Find method of the ContactItems collection. That and to search ALL of the email fields.

Our business logic is done. Let’s wire our methods to our UI events and add-in events.

Wiring the code to Outlook events

We are on the home stretch. This last bit might require an additional 5-10 minutes. Let’s first add the code to our buttons.

The button click events

The easy way to attach the code to our custom Outlook buttons is to copy and paste the code below. In fact, this is exactly what I recommend you do.

VB.NET code sample

#Region "Button Events"
  Private Sub btnCreateTask_OnClick(ByVal sender As System.Object, _
	ByVal control As AddinExpress.MSO.IRibbonControl, _
	ByVal pressed As System.Boolean) Handles btnCreateTask.OnClick
 
    CreateLinkedItem(Outlook.OlItemType.olTaskItem)
  End Sub
 
  Private Sub cbbCreateTask_Click(ByVal sender As System.Object) _
	Handles cbbCreateTask.Click
 
	CreateLinkedItem(Outlook.OlItemType.olTaskItem)
  End Sub
 
  Private Sub btnCreateAppointment_OnClick(ByVal sender As System.Object, _
	ByVal control As AddinExpress.MSO.IRibbonControl, _
	ByVal pressed As System.Boolean) Handles btnCreateAppointment.OnClick
 
    CreateLinkedItem(Outlook.OlItemType.olAppointmentItem)
  End Sub
 
  Private Sub cbbCreateAppointment_Click(ByVal sender As System.Object) _
	Handles cbbCreateAppointment.Click
 
	CreateLinkedItem(Outlook.OlItemType.olAppointmentItem)
  End Sub
 
  Private Sub cbbCreateNote_Click(ByVal sender As System.Object) _
	Handles cbbCreateNote.Click
 
	CreateLinkedItem(Outlook.OlItemType.olNoteItem)
  End Sub
 
  Private Sub btnCreateNote_OnClick(ByVal sender As System.Object, _
	ByVal control As AddinExpress.MSO.IRibbonControl, _
	ByVal pressed As System.Boolean) Handles btnCreateNote.OnClick
 
    CreateLinkedItem(Outlook.OlItemType.olNoteItem)
  End Sub
#End Region

What we have here is six Click events that call CreateLinkedItem, each passing a parameter for the type of Outlook item to create.

Handling Explorer Selection Change

When the user selects a new item within the Outlook Explorer, Outlook triggers the ExplorerSelectionChange event. This event is the perfect location for the code that calls GetContactInfo and responds accordingly.

To make this happen for us we need 1) add Add-in Express Outlook Events component and 2) write code against it. To handle the first step, open the AddinModule in design view. Then click the Application Level Events button residing in the module’s toolbar (look at the end of the right-hand side… the one with the lightning bolt). In the options that display, click the Microsoft Outlook Events button.

We now have a component that allows us to attach code to Outlook’s events. The only event we need is the ExplorerSelectionChange event. Add the following code to AddInModule.

VB.NET code example

Private Sub adxOutlookEvents_ExplorerSelectionChange(ByVal sender As System.Object, _
	ByVal explorer As System.Object) Handles adxOutlookEvents.ExplorerSelectionChange
 
    Dim olExplorer As Outlook.Explorer = DirectCast(explorer, Outlook.Explorer)
    Dim sel As Outlook.Selection = Nothing
    Try
      sel = olExplorer.Selection
    Catch
    End Try
 
    If sel IsNot Nothing Then
      If sel.Count > 0 Then
 
        Dim email As Outlook.MailItem = TryCast(sel.Item(1), Outlook.MailItem)
        If email IsNot Nothing Then
 
          Dim form As ContactInfo = _
			DirectCast(AdxOlFormsCollectionItem1.GetForm(olExplorer), ContactInfo)
 
          If form IsNot Nothing Then
            If Not GetContactInfo(email.SenderEmailAddress) Then
 
              form.Hide()
 
            Else
              With form
                .lblFullName.Text = _ContactFullName
                .lblTitle.Text = _Title
                .lblCompany.Text = _Company
                .lblBusinessPhone.Text = _BusinessPhone
                .lblMobilePhone.Text = _MobilePhone
                .Visible = True
                .Show()
              End With
            End If
          End If
 
          Marshal.ReleaseComObject(email)
        End If
      End If
 
      Marshal.ReleaseComObject(sel)
    End If
  End Sub

This event begins by testing for a valid Selection. If a Selection exists and its count is above 0, we are ready to proceed. We do so by grabbing the first item in the Selection collection. We could grab all of them but I will leave that to you as a challenge. It shouldn’t be too difficult should you choose to take it on.

Using the selected mail item, we grab a reference to the ContactInfo form. This ref The for a valid Selection. IF erence is made easy to achieve thanks to the AdxOlFormsCollectionItem’s GetForm method.

We then call GetContactInfo and branch the code depending on if we have a valid contact or not. If not, we simply hide ContactInfo. If we do have a valid contact, we fill labels and display the form. It’s quite elegant!

Outlook 2010 add-in in action

We are now done with the building and can take tour Outlook plug-in for a spin. I recommend that you build the project, register it on your system, and hit F5 to see it action. Or, you can watch me do this in the video below.

Video: Contact Info form in Outlook

Available downloads:

This sample addin was developed using using Add-in Express for Office and .net:
VB.NET – Ty Actions Outlook Add-in

How to write better Outlook add-ins

Post a comment

Have any questions? Ask us right now!