Crash in GetMAPIOBJECT + Outlook 2007

  • Thread starter Thread starter pete_42
  • Start date Start date
P

pete_42

Hi,

I'm using the following code to get the IMAPIProp-Pointer to the
current Outlook mail window. Worked nicely so far. But when I'm testing
it with Outlook 2007 beta, the GetMAPIOBJECT call causes an exception.

If I perform the same steps as the program below does with OutlookSpy
and Outlook 2007 everything works nicely - so what am I doing wrong,
here? I'd be grateful for any ideas...

THANKS!

pete

Outlook::_InspectorPtr spInspector = m_OLAppPtr->ActiveWindow();
if (spInspector)
{
IDispatch *pd = spInspector->GetCurrentItem();
if (pd)
{
Outlook::_MailItem *pMailItem = NULL;
const GUID local_IID_IMailItem = {0x00063034,0,0,
{0xC0,0,0,0,0,0,0,0x46}};
pd->QueryInterface (local_IID_IMailItem, (LPVOID *)&pMailItem);

if (pMailItem)
{
IUnknown *iu = pMailItem->GetMAPIOBJECT(); //Crashes in
Outlook 2007 Beta
.....
 
Where is your code running? Is it in the outook.exe process space (your code
is a COM add-in) or in a separate exe?

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
 
Hmmm... What kind of exception is it? A COM error or something like an
access violation?

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
 
Dmitry said:
Hmmm... What kind of exception is it? A COM error or something like an
access violation?
Good question. I tried 3 catch'es:
catch(_com_error &)
catch (CException *)
catch (...)

The third one caught the exception. So it's probably an access
violation.

Can the pointer be wrong?
Am I doing a bad cast somehow??
 
What happens when you run your code under the debugger? Did you set "break
on exception" for all exceptions in Debug | Exceptions dialog?

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
 
Took some time, but I got some
1. pMailItem->Save();
Works most of the time. (Currently I don't worry about RARE crashes)
2. pMailItem->get_MAPIOBJECT(...);
Works most of the time, about always yields a NULL pointer.
3. pMailItem->get_Class(...)
Works most of the time and yields 43.

=> So the pMailItem Pointer should be correct.

If I compile my DLL in debug mode (Previously I used release mode for
an easier deployment on the other PC), I get an error messagesaying
the ESP wasn't properly restored, probably because of differing calling
coventions. So I guess that my include files (Generated from Outlook
2000) are bad.

Quoting from msoutl9.tlh:
__declspec(property(get=GetMAPIOBJECT))
IUnknownPtr MAPIOBJECT; and
virtual HRESULT __stdcall get_MAPIOBJECT (
IUnknown * * MAPIOBJECT ) = 0;


Quoting from msoutl9.tli:
#pragma implementation_key(564)
inline IUnknownPtr Outlook::_MailItem::GetMAPIOBJECT ( ) {
IUnknown * _result;
HRESULT _hr = get_MAPIOBJECT(&_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return IUnknownPtr(_result, false);
}

But this yields new questions:
- Does GetMAPIOBJECT really call get_MAPIOBJECT? If so, why don't I get
a crash for the latter and why does Microsoft recommend no to use
get_MAPIOBJECT?
- Is the include bad? And how? Is _stdcall or HRESULT or IUnknown
defined wrong by some include?
- Is there another way to call the function? Some generic
Invoke/Message/Whatever?
- Which call do you perform in OutlookSpy when I doubleclick the
MAPIOBJECT item in the CurrentItem() View?

Thanks.
 
Don't know about the headers - I don't use VC++. Did you try to create new
headers using the Outlook 2007 type library?
OutlookSpy always uses late binding when retrieving that property - call
IDispatch::GetIDsOfNames("MAPIOBJECT", ...) then IDispatch::Invoke().

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
 
YESYESYES!!!!! :)

Now it works. If I Invoke() the call manually it works. But now I found
a different problem. :(

Once I Save an unsaved mail, the "pMailItem" seems to become bad. I
can't pMailItem->Release it. Or Invoke Save again. Both causes a crash.

Does the Save invalidate the pMailItem? Don't I have to release it? Or
do I have to wait for the Save to finish? Somehow...
 
I have never seen or heard about such a problem with MailItem.Save.
I strongly suspect that something happens in your code :-)

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
 
Dmitry said:
I have never seen or heard about such a problem with MailItem.Save.
I strongly suspect that something happens in your code :-)

I know, it sounds very suspicious. (For me, too ;-) But now, when I
Save an Item that has not been saved previously I call ActiveWindow()
and GetCurrentItem() again (basically re-getting the pointer) and it
works. I've removed the QueryInterface-Call to the GetCurrentItem()
result, so there shouldn't be memory leaks.

Don't ask me why, but it works.

Dmitry, thanks a lot for all your help and comments!
 
So you call Save on an item that is being displayed?
Can you check the evalue of MailItem.Parent.Name before and after saving?

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
 
Dmitry said:
So you call Save on an item that is being displayed?
Yes. Because I want it to have an PR_ENTRYID member.
Can you check the evalue of MailItem.Parent.Name before and after saving?
Didn't try that. But if you're really interested, I can do that.

My impression is that the Save() Call to an unsaved message makes the
MailItem-Pointer invalid (under Outlook 2007). Perhaps the item is
somehow moved/converted/copied, because I think the Problem occurs only
for a Save() call on an unsaved item. Because even Release() failed (on
the copy that I got with QueryInterface) I doubt that any other call
would succeed.
 
Dmitry, did you notice that the tooltip for the OutlookSpy button
"Application" is multi-line for the main window, but not when the
button appears in a mail window?

Is that an Outlook 2007 bug?

Wouldn't be the only one. I've noticed that you don't get reasonable
values when you query a toolbar button's size or position...
 
You need to include the carriage return (0xD, 0xA) in the string that you
assign to the CommandBarButton.ToolTipText property.

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
 
Back
Top