Strange Looking NDR


Not many people are aware of the feature, but MFCMAPI implements a MAPI Form Viewer. This means MFCMAPI can use MAPI to ask Outlook to display messages. You might have run into this if you ever double-click on a message in MFCMAPI. If you’re on a machine with Outlook installed, the message will open up like it does when you double-click it in Outlook. And if Outlook isn’t installed and you’re using Exchange’s MAPI, you get a scary dialog saying we couldn’t open the MAPI form manager.

This is one of those dark corners of MAPI into which few people tread, and most of those who do end up cribbing or parroting the Form Viewer implementation in MFCMAPI itself, meaning nearly every issue they report related to form viewers can be reproduced in MFCMAPI. Sometimes, this turns out to be a bug in my implementation, like an errant warning while clicking up and down through messages (fix coming very soon!). Other times, the problem is a bug in Outlook.

My latest customer’s issue turned out to be the latter case. They had noticed that when they tried to view NDR messages with their Form Viewer, the body of the message would be full of alien looking RTF text:

“{rtf1ansiansicpg1252deff0deflang1033{fonttbl{f0fmodernfcharset0 Consolas;}}
{*generator Riched20 12.0.6413.1000;}viewkind4uc1
pardfi-1440li1440tx1440f0fs21 Your message did not reach some or all of the intended recipients.par
etc…”

What was really odd was that if you looked at the message in MFCMAPI, this text was no where to be found! And to top it off – if you opened the message from Outlook, you got the NDR message you expected.

So what was going on? It’s not surprising that Outlook builds the NDR text on the fly. It’s much easier to localize it that way. And the RTF does appear to be the underlying RTF we would generate for the NDR message. But why did we display it wrong, and why did Outlook display it right?

The key here is the LoadForm function. This function takes the message class of the form we want to load. Under the covers, LoadForm looks up the message class using ResolveMessageClass and gets the GUID for the associated class factory. The form manager then passes this GUID over to Outlook and asks for the class factory. This is where we have a problem. Outlook uses the same GUID for multiple form class factories, some of which have different attributes associated with them. The class factory we get has an attribute on it stating it should render using HTML, while the class factory we should have gotten did not have this attribute. So when it comes time to render the text, we use the wrong rendering method and get the ugly RTF text.

When Outlook opens the message, being the implementer of the forms, it gets to skip many of the MAPI steps. Instead of using the message class to look up a GUID, it uses the message class to look up the class factory directly, getting the right one in the process.

Based on the fact that this behavior has been unchanged for as long as we can trace back, and we’re only just now hearing of an issue with it, we chose not to fix this problem, but instead document it. So – here’s the documentation. Enjoy!

Comments (2)

  1. So can I programmatically do the same look up as Outlook to retrieve the right form factory?

  2. Stephen Griffin says:

    I don’t think so (since Outlook’s not consulting a published list, but rather an internal array), but if you figure anything out let us know.