Thursday, June 09, 2005 3:27 AM bart

Personal messages in MSN 7.0 with C# (cont'd) - Integrating Outlook Calendar

In the previous post I blogged about the general techniques to communicate with MSN 7.0 to change the personal message. In this blog post I'm going to take it a little step further, by writing an Outlook 2003 add-in that updates the MSN personal message with the current item in your calendar (e.g. "Jogging", "Meeting with XYZ", "Conference call ABC").

These are the steps to create such an add-in successfully:

  1. Open Visual Studio .NET 2003 and create a new project. In the "New Project" dialog choose Other Projects, Extensibility Projects, Shared Add-in and give the project a meaningful name.
  2. In the Add-in Wizard click Next. Choose to "Create an Add-in using Visual C#" and click Next. In the next step, uncheck every checkbox in the list except for "Microsoft Outlook" and click Next again. Now, give a name to the plug-in and (optionally) a description. Click Next. Check both checkboxes in the next step, i.e. to load the Add-in when the host app (in this case Outlook) starts and to install the plug-in for everyone on the target computer. Click Next and Finish.
  3. Now you'll end up with a Connect.cs file containing the plug-in class with all the add-in related plumbing in place.
  4. Import the code from the previous blog post in this class. This includes the Win32 function imports, the struct for IPC messages and the methods VarPtr, SendMSNMessage and RemoveMSNMessage.
  5. Now it's time for the real (Outlook-related) work.

The next fragment contains the code for the OnConnection method where we will launch the add-in:

public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom)
{
    applicationObject = application;
    addInInstance = addInInst;

    //
    //Outlook object and calendar folder
    //
    outlook = (Outlook.Application) applicationObject;
    cal = outlook.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);

    //
    //Watch calendar
    //
    cal.Items.ItemAdd += new
Outlook.ItemsEvents_ItemAddEventHandler(Items_ItemAdd);
    cal.Items.ItemChange +=
new
Outlook.ItemsEvents_ItemChangeEventHandler(Items_ItemChange);
    cal.Items.ItemRemove +=
new
Outlook.ItemsEvents_ItemRemoveEventHandler(Items_ItemRemove);

    //
    //Timer to crawl through the calendar on a regular basis
    //
    timer = new
System.Timers.Timer(10000);
    timer.Elapsed +=
new
System.Timers.ElapsedEventHandler(timer_Elapsed);

    if
(connectMode != Extensibility.ext_ConnectMode.ext_cm_Startup)
        OnStartupComplete(
ref
custom);
}

In here, a couple of private attributes are used:

private object applicationObject;
private
Outlook.Application outlook;
private object
addInInstance;
private
System.Timers.Timer timer;
private Outlook.MAPIFolder cal;

The declared events for the timer and the three Calendar-events look like this:

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    Search();
}

private void Items_ItemAdd(object
Item)
{
    Search();
}

private
void Items_ItemChange(object Item)
{
    Search();
}

private
void Items_ItemRemove()
{
    Search();
}

Apparently the method Search has a significant role ;-). Let's show you:

private void Search()
{
    //
    //Get calendar items, including recurring appointments
    //
    Outlook.Items i = (Outlook.Items) cal.Items;
    i.IncludeRecurrences =
true
;

    //
    //Query the result based on the current date/time and the sensitivity
    //
    string
d = DateTime.Now.ToString("MM/dd/yyyy HH:mm tt");
    string
criterion = String.Format("[Start] <= \'{0}\' and [End] >= \'{0}\' and [Sensitivity] <> {1}", d, (Int32) Outlook.OlSensitivity.olPrivate);
    Outlook.Items events = i.Restrict(criterion);
    events.IncludeRecurrences =
true
;

    //
    //We'll give the first appointment in the range priority
    //
    Outlook.AppointmentItem a = (events.GetFirst() as
Outlook.AppointmentItem);

    //
    //Did we find an appointment that suits our criteria?
    //
    if (a != null
)
    {
        //
        //Determine additional status information for the personal message
        //
        string
b = "";
        switch
(a.BusyStatus)
        {
            case
Outlook.OlBusyStatus.olOutOfOffice:
                b = "OOF";
                break
;
            case
Outlook.OlBusyStatus.olBusy:
                b = "Do not disturb";
                break
;
        }

        //
        //Set the MSN personal message
        //
        SetMSNMessage("Outlook - " + a.Subject + (b != "" ? " (" + b + ")" : ""));
    }
    else
    {
        //
        //No, remove the MSN personal message
        //
        RemoveMSNMessage();
    }
}

The magic work in here is the filtering of the Calendar folder using some MAPI-related functionality. The formatting of the date is mandatory as the filter needs to have the right format (e.g. "01/01/2001 01:01 AM", thus no seconds and AM/PM spec). Also recurring appointments are included. For "OutOfOffice" and "Busy" items, a short string is added to the personal message which always contains the prefix "Outlook - " (as we will show the Office logo using SetMSNMessage, see previous post) and the Subject of the appointment. Note that the filter also avoids the display of "private items" as you probably don't want other people to know about your private appointments with ... euhm ... your mistress or so :o.

The last missing pieces are some other events for the add-in:

public void OnStartupComplete(ref System.Array custom)
{
    //
    //Start timer
    //
    timer.Start();
}

public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode, ref System.Array custom)
{
    if(disconnectMode != Extensibility.ext_DisconnectMode.ext_dm_HostShutdown)
        OnBeginShutdown(
ref custom);
    applicationObject =
null;
}

Now, we're done. Just build the solution and launch Outlook. The COM-based add-in will be registered automatically (take a look at HKLM\Software\Microsoft\Office\Outlook\Addins) and thus it should be launched when you start Outlook. Every time you create, delete or modify an appointment, the add-in will come in action and look whether a change of the personal message is required instantaneously. Beside of the event-based updates, the timer will fire every 10 seconds to crawl through the Calendar in order to find appointments that need to be displayed. If there's overlap, only the first appointment in the list will be shown (you can change this behaviour by calling the Order method on the Outlook.Items variable that is used to do the filtering).

Finally, if you want, you can build the (automatically generated) installer project in order to have a MSI-based installer for the add-in you wrote. You can download a compiled version with installer on http://www.bartdesmet.net/download/OutlookMsnPluginSetup.zip. Please note that the author is not responsible for any damage whatsoever caused by installing and/or running this plug-in. Although I'm quite sure this build is bug-free, it was not thoroughly reviewed prior to submission to the download section of my website.

This is how the result should look:

Have (even more) fun :-)

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Filed under: ,

Comments

# re: Personal messages in MSN 7.0 with C# (cont'd) - Integrating Outlook Calendar

Thursday, June 09, 2005 10:37 PM by bart

Hi Bart.

Unless I'm very much mistaken (or in other words: blind), you forgot to include the definition for the VarPtr function in your previous post. I'd appreciate it if you could still post it here...
Tnx.

# re: Personal messages in MSN 7.0 with C# (cont'd) - Integrating Outlook Calendar

Thursday, June 09, 2005 11:00 PM by bart

Hi Patrick,

Completely right; I forget to include the function in my initial post. It's in there right now. Enjoy it!

Cheers,
Bart

# re: Personal messages in MSN 7.0 with C# (cont'd) - Integrating Outlook Calendar

Thursday, June 23, 2005 2:13 PM by bart

I must admit to being more impressed for it. I've even recommended it to all my friends.

# re: Personal messages in MSN 7.0 with C# (cont'd) - Integrating Outlook Calendar

Saturday, June 25, 2005 10:30 AM by bart

I have been using it. Outlook Express more stable and secure than other programs.

# MSN 7 Winamp support

Sunday, July 24, 2005 2:05 PM by TrackBack

# MSN 7 Winamp support

Sunday, July 24, 2005 2:23 PM by TrackBack

# re: Personal messages in MSN 7.0 with C# (cont'd) - Integrating Outlook Calendar

Wednesday, August 24, 2005 4:09 PM by bart

If i would like to make a random personal message with quote, what should i start with?

Thankz. =P

# re: Personal messages in MSN 7.0 with C# (cont'd) - Integrating Outlook Calendar

Wednesday, October 12, 2005 3:52 PM by bart

where is the previous post? can u post a link to that please

# re: Personal messages in MSN 7.0 with C# (cont'd) - Integrating Outlook Calendar

Wednesday, October 12, 2005 4:47 PM by bart

# re: Personal messages in MSN 7.0 with C# (cont'd) - Integrating Outlook Calendar

Wednesday, October 19, 2005 2:41 PM by bart

No RemoveMSNMessage method

# visit this site right here

Thursday, September 11, 2014 12:51 PM by visit this site right here

Personal messages in MSN 7.0 with C# (cont'd) - Integrating Outlook Calendar - B# .NET Blog