Problem displaying mail items from within a new thread

G

Guest

Hello all,


I'm developing and outlook addin in ATL/C++. Environment is VS2005 &
Outlook2003. I want to display mail items from my addin. If I call to
pMailItem->Display() from within an OnNewMail sink function, it works just
fine. However, if I create a thread and call the above from within that
thread, I get an error code 0xdcd04005 and the following in the debugger
output window:



First-chance exception at 0x7c81eb33 in OUTLOOK.EXE: 0x80004002: No such
interface supported.

First-chance exception at 0x7c81eb33 in OUTLOOK.EXE: 0x80004002: No such
interface supported.

First-chance exception at 0x7c81eb33 in OUTLOOK.EXE: 0x80004002: No such
interface supported.

First-chance exception at 0x7c81eb33 in OUTLOOK.EXE: 0x80004002: No such
interface supported.

First-chance exception at 0x7c81eb33 in OUTLOOK.EXE: 0x80004002: No such
interface supported.

First-chance exception at 0x7c81eb33 in OUTLOOK.EXE: 0x8001010D: An outgoing
call cannot be made since the application is dispatching an input-synchronous
call.

'OUTLOOK.EXE': Loaded 'C:\Program Files\Common Files\Microsoft Shared\Smart
Tag\IETAG.DLL', No symbols loaded.

First-chance exception at 0x7c81eb33 in OUTLOOK.EXE: 0x80004002: No such
interface supported.

First-chance exception at 0x7c81eb33 in OUTLOOK.EXE: 0x80004002: No such
interface supported.

First-chance exception at 0x7c81eb33 in OUTLOOK.EXE: 0x8001010D: An outgoing
call cannot be made since the application is dispatching an input-synchronous
call.

First-chance exception at 0x7c81eb33 in OUTLOOK.EXE: 0x80004002: No such
interface supported.

First-chance exception at 0x7c81eb33 in OUTLOOK.EXE: 0x80004002: No such
interface supported.

First-chance exception at 0x7c81eb33 in OUTLOOK.EXE: 0x8001010D: An outgoing
call cannot be made since the application is dispatching an input-synchronous
call.

And also outlook becomes unstable. That is, sending mail messages hungs
outlook.

How can I display mail items from within my thread? All other methods of
pMailItem works fine also from within the thread, only Display() fails.

Need help.

Thanks a lot in advance.
 
D

Dmitry Streblechenko

First of all, why would you want to? What exactly do you do on that thread?
You cannot easily use Outlook objects on a secondary thread (see below).
All Outlook objects are apartment threaded, so you must either
1. call CoMarshalInterface/CoUnmarshalInterface if you want to use a COM
object retrieved from one thread in another thread
2. Retrieve the message to be displayed from a COM object in the same
thread, i.e. create a brand new instance of Outlook.Application on the
secondary thread and call Namespace.GetItemFromID. Note however that both #1
and #2 will result to your secondary thread switching to the main thread, so
you loose all the benefits of multithreading and incur an extra expense of
thread switching.
3. I would personally prefer this one - make the secondary thread completely
UI-less and OOM-free, then just pass the results from the secondsary thread
back to the main thread.
4. Do all of your processing on the main thread. If it takes too long, think
about optimizing your algorithm. What exactly are you trying to do?

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

Dmitry Streblechenko

Why not simply use a timer? If the check is time consuming, you can launch
a secondary thread, and then simply set a global variable and check it every
once in a while on the main thread in the timer event handler.

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

Boaz Feldbaum

What my add-in suppose to do is to recognize some proprietary attachment in
new mail messages. This kind of attachment has an expiration time. So I set
a timer to expire before the expiration time and warn about that the
attachemnt is about to expire. The thing is that I want to be able to let
the user open the mail item from within my UI.. I may have several such
attachments so I create a thread that waits for the next expired attachment.
How can I make the main thread display the mail item? I have another thread
that periodically scanns the current folder and changes the status of the
attachment to non-valid, if it becomes non-nvalid. An attachment may become
non-nvalid also becasue of external events, not only expiration. So how can
I do this periodic scan in the main thread?

If I marshal the application object, everything works well but outlook never
exit. Is there some additional cleanup that needs to be done?

My marshaling code looks like this:

static HRESULT WritePtr(Outlook::_Application *pApp, HGLOBAL &hGlobal)
{
HRESULT hr;
CComPtr<IStream> pStm;

hGlobal = NULL;

// Alloc and wrap block of memory
hr = CreateStreamOnHGlobal(NULL, FALSE, &pStm);
if (FAILED(hr))
{
return hr;
}

// Write marshaled object reference to memory
hr = CoMarshalInterface(pStm,
__uuidof(Outlook::_Application),
pApp,
MSHCTX_INPROC,
0,
MSHLFLAGS_NORMAL);
if (FAILED(hr))
{
return hr;
}

// Extract handle to underlying memory
hr = GetHGlobalFromStream(pStm, &hGlobal);
if (FAILED(hr))
{
return hr;
}

return S_OK;
}

static HRESULT ReadPtr(HGLOBAL hGlobal, CComPtr<Outlook::_Application>
&pApp)
{
HRESULT hr;
CComPtr<IStream> pStm;

pApp = NULL;

// Wrap block of existing memory passed on input.
hr = CreateStreamOnHGlobal(hGlobal, FALSE, &pStm);
if (FAILED(hr))
{
return hr;
}

// get a pointer to the object that is legal in this apt.
hr = CoUnmarshalInterface(pStm,
__uuidof(Outlook::_Application),
(void**)&pApp);
if (FAILED(hr))
{
return hr;
}

return S_OK;
}
 
B

Boaz Feldbaum

Please excuse my ignorance, how to get a timer event in the main thread?

Can you also please explain why does the marshling code causes outlook to
hung on exit?
 
D

Dmitry Streblechenko

You will need to create your own (hidden) window, call SetTimer, then
process the WM_TIMER message. I don't use VC++, but I am sure there is a
helper class that does that for you.
As for Outlook hanging, most likely you are leaking a reference - hard to
say without seeing all of your source code and running it under a debugger.

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

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top