Miscellaneous Debris

Avner Kashtan's Frustrations and Exultations

January 2007 - Posts

Exposing add-in errors in VSTO for Word 2007

One of the most annoying things about writing add-ins for Office is that it tends to swallow any and all errors that occur. All exceptions are silently thrown into the trash heap without even a statusbar flag. Nothing. This meant that we often had to add messageboxes for debugging, or Debugger.Launch to see what's going on.

At first I thought that Word 2007 was no different, but then I was idly browsing through the Word Options dialog and discovered a wonderful prize - a checkbox called "Show add-in user interface errors". Quickly checked and lo and behold - exceptions in my code are shown by Word! Life is good again!

So in case you've missed it too (and it's easy to miss), it's under the Office/File menu -> Word (or Excel) Options -> Advanced:

 

Enjoy!

Posted: Jan 21 2007, 06:10 PM by Avner Kashtan | with 2 comment(s)
Filed under: ,
Zune Desktop Theme - A Warning

 

A few days ago, Microsoft released a new Desktop Theme for Windows XP named the "Zune Desktop Theme" – even though it looks a lot like Vista, all in black and orange. It fits in with Office 2007's Black skin, so I gleefully installed it.

Everything was fine for a few days until the first time I had to reboot (rather than Standby/Hibernate) – late last night. From that moment on, my Windows Explorer would crash every time you tried to do anything. Windows loaded? Explorer crashed. Tried to open a folder? Expolrer crashed. Save As from Word? You guessed it.

Took me a while to put two and two together since there were a few days between the two, but the solution is to:

a) Uninstall the Zune Desktop Theme.

b) Choose a different desktop theme (Luna, for instance).

c) Reboot.

This solved the problem for me. Even though I'd gotten used to the gloomy Vista-ish look, I won't be reinstalling it any time soon. Your experience might be different, but beware. If you're feeling curious or suicidal, here's the download link:

Zune XP Desktop Theme

VSTO for Outlook 2007 - Building the Add-in (part 2)

Writing the Outlook add-in described in my previous post was composed of the following steps:

1) Creating the project

Ah, the wonders of VSTO. Saving us all the unnecessary hassle of adding COM references, implementing interfaces and working too hard. After installing VSTO 2005 SE we can create a new Outlook 2007 Add-in project that creates both the add-in project and the MSI Setup project that can be used to install it.

2) Building the Context Menu

To add my own menu items to each item's Context Menu, I use the new ItemContextMenuDisplay event that is exposed by the Outlook 2007 object model. In the pre-supplied Startup method I simply add the following event registration:

this.Application.ItemContextMenuDisplay += new Microsoft.Office.Interop.Outlook.ApplicationEvents_11_ItemContextMenuDisplayEventHandler(Application_ItemContextMenuDisplay);

In my event handler method I start by fetching the current Outlook folder:

MAPIFolder currentFolder = Application.ActiveExplorer().CurrentFolder;

and creating the root of the popup menu tree:

// Create a new button in the commandBar. The command bar itself is received as a parameter to the event
// handler  method.

CommandBarPopup rootButton = (CommandBarPopup)commandBar.Controls.Add
(Office.MsoControlType.msoControlPopup, Type.Missing, "MoveToFolder", commandBar.Controls.Count + 1, Type.Missing);
 

rootButton.BeginGroup = true;
rootButton.Tag = "MoveToSubFolder";
rootButton.Caption = "Move To...";
rootButton.Visible = true;

Now I recursively go over the current folder and its subfolders, adding new buttons under the rootButton as I go along.

Things to note:

  •  I create a different menu control depending on whether I'm creating a leaf node or a node that has children - one is a Button, the other a Popup. For some reason I couldn't create a PopupButton, maybe it's a control that's reserved for a toolbar and can't be used in a ContextMenu. This means that a node with children cannot be clicked, and we can't copy items to it. There may be a workaround to this using the OnAction property rather than the Click event, but I haven't gotten around to checking it out. I'd appreciate feedback.
  • I'm saving the FullFolderPath in each node's Tag object. This is so I can access it later when I'm moving the items. I originally wanted to save the EntryID + Store's EntryID in the Tag for a totally unique identifier, but for some reason Outlook crashed whenever I tried to save that in it. I have no idea why.
  • Note the recursion - each folder is addings its leaf-nodes as buttons, and sending each non-leaf children to another call to AddFolder.
private void AddFolder(MAPIFolder folder, CommandBarPopup menu)
{
      foreach (MAPIFolder subFolder in folder.Folders)
      {
MsoControlType linkType = (subFolder.Folders.Count > 0) ? 
               MsoControlType
.msoControlPopup : MsoControlType.msoControlButton;

     
CommandBarControl folderLink = menu.Controls.Add
(linkType, Type.Missing, subFolder.Name, 1, Type.Missing);
 
            folderLink.Tag = subFolder.FullFolderPath; 
            folderLink.Caption = subFolder.Name;

 
            if (linkType == MsoControlType.msoControlPopup)
            {
AddFolder (subFolder, folderLink as CommandBarPopup);
            }
            else
            {
(folderLink as CommandBarButton).Click += new
                             _CommandBarButtonEvents_ClickEventHandler
(
            MoveToFolder);
            }             
      }
}

3) Moving the items

As we could see above, each leaf node's Click event is handled by the MoveToFolder method:

Again, noteworthies:

  • The FullFolderPath we saved earlier is translated to a MAPIFolder object using the GetFolderFromPath function, a glaring omission in the Outlook object model that we have to rectify by hand. I'll post the full (and simply) code for this in a different post. It's included in the attached project. 
  • Note that we're casting the items in the current selection to MailItem objects, meaning standard outlook email messages. We're ignoring non-MailItems in this code. Since the COM object model doesn't give us any shared base-classes or interfaces for other entities, we need to write some ugly code to handle PostItems, AppointmentItems and so forth.

 

 
void MoveToFolder(CommandBarButton Ctrl, ref bool CancelDefault)
{
          MAPIFolder destFolder = GetFolderFromPath(Ctrl.Tag);
 
          foreach (object item in Application.ActiveExplorer().Selection)
          {
                    MailItem mi = item as MailItem;
                    if (mi != null)
                    {
                             mi.Move(destFolder);
           }
                    else
                    {       
                             // Can only copy MailItems;
                    }
          }
}

4) Profit!

Well, maybe not. But this is the entire extent of the code needed to implement this add-in. I've attached the whole project (including the MSI project) so you can install it at home, or use the code as a base for whatever add-in you feel like writing. The pre-built MSI is in the MoveToFolderAddInSetup\Debug folder. Enjoy!

VSTO for Outlook 2007 - New Features, More Fun (part 1)

Introduction

Outlook has always been a bit of a latecomer to the VSTO game, being a step behind and a version later than Word and Excel. I'm glad to see that with Outlook 2007 and VSTO 2005SE it's gotten simpler and easier to write add-ins for it. So I did.

The basic premise of this was an exercise to know more of the new Object Model enhancements in Outlook 2007, but it best serves as an example of a add-in for Outlook that uses the VSTO environment and the abilities of the new version.

The Goal

Lately I've found my inbox exploding with many new subfolders. Lots of new projects and tasks that accumulate messages and information. Since I don't subscribe (yet?) to the "Search, don't Sort" philosophy, I tend to group my correspondences into subfolders in some intricate and arcane hierarchy. Outlook 2007 gives me three methods of copying messages from my inbox to the relevant folder:

1) Rules. The problem here is that I don't always know in advance who the mail will be coming from or what will be on the subject line.

2) Drag&Drop. Necessitates keeping my folder tree open to its full depth, or else waiting for the interminable timeout until the tree expands itself. Also, no keyboard support.

3) Move To Folder dialog. This allows me select several items and move them en masse to a new folder. The problem here is that it opens a whole dialog for me to traverse (like in the Drag & Drop scenario above) until I can move my items. Move clicks, more UI to go through.

As you can see, I'm not thrilled with either one of these alternatives, so I decided to add a fourth.

The Solution

A solution that was suggested to me a while ago was, unfortunately, very hard to implement using Office 2003. The idea is to add a new menu item to an item's Context Menu in Outlook that will allow quick access to all subfolders. This will allow a two-click moving (one to raise the context menu, another to choose the destination). It also allows keyboard navigation and selection, making it easier for those times when I'm experiencing mouse fatigue.

There are some problems and limitations with my current implementation, an admittedly quick'n'dirty solution. The first is that I currently only support moving MailItems, meaning normal Outlook messages. It currently won't work for tasks, appointments or Public Folder posts. This isn't really a problem for most scenarios, but if someone needs that functionality, it should be added.

Another problem is that you can only move items to a leaf folder - if I have a Projects->Sharepoint->NewSharepointProject hierarchy, I can't copy my items to the Projects or Sharepoint folders. This is probably solvable, but I decided against confornting the Office Commandbars for now. I'll elaborate more later when I talk about the code.

The Code

This has gotten longer than I expected, so I'll be splitting the actual code of the add-in to a different post. Here's the link to the second part: The Add-in Code post.

Screenshots

(For the sake of politeness I've blacked out most of my inbox. Do not be alarmed. Don't try to adjust your sets)

Posted: Jan 03 2007, 02:59 PM by Avner Kashtan | with 5 comment(s)
Filed under: ,
More Posts