New Inspector event in OL2000 when using Word as Editor

  • Thread starter Thread starter Jim
  • Start date Start date
J

Jim

Hi,

We're working on an OL2000 COM addin that adds menu to New Mail
window. Based on online literature, we should handle the New Inpsector
event, however we found this event will not fire when using Word as
email editor. We found the following KB which confirms the behavior:
http://support.microsoft.com/kb/218298/en-us

My questions are:
1. Is this behavior still true for OL2000 SP3 and there is no way to
get the New Inspector event in OL2000 as long as Word is used as
editor?
2. If so, what is the recommended workaround for this behavior?
3. There are some suggestions on using a Word addin to handle this
case, are there examples on using Word addin together with Outlook?
4. If we do use Word addin, do we use Word object model? If we do use
Word object model, how does it handle mail aspect of the document, for
example subject/attachment?

Thanks

Jim
 
No level of Outlook 2000 fires NewInspector() when a WordMail Inspector is
opened.

I've never been happy with any attempts to use a Word addin to try to handle
WordMail due to how msword.exe is subclassed by Outlook for use in WordMail.

The best workaround I've found is a timer that checks the count of the
Inspectors collection. If an Inspector is extant and not included in your
Inspector wrapper collection then it's either a WordMail object or a Simple
MAPI Inspector (opened using Send To Mail Recipient or a variant of Send
To).

If an Inspector is a Simple MAPI Inspector it will always use the Outlook
editor and not WordMail, so an easy test if you find an unhandled Inspector
in the Inspectors collection is to check and see if Inspector.IsWordMail is
True.
 
Hi, Ken:

Thanks for the idea, we're going to give timer a try. I wonder if you
could give some suggestion on:
1. What is the recommended timer interval?
2. Since our goal is to add a menu to New Mail window, I assume once
we find a Word Mail inspector, we'll use an inspector wrapper on it,
right? However, I think the inspector wrapper relies on the activate
event of the inspector to add the menu, if we use a timer, is it
possible that before we have a chance to add the inspector to wrapper,
the activate event is already fired? How do we handle this case?

Thanks

Jim
 
Use whatever timer interval you want. Too short an interval and you will bog
down your code and Outlook with checking for unhandled Inspectors. Too long
and it will show an appreciable delay in when the UI is shown after the
Inspector is opened. Usually somewhere between 10 and 45 seconds is OK, but
you have to evaluate that yourself.

You'll also need to handle cases where your timer fires before or during
NewInspector for non-WordMail Inspectors and make sure you don't replicate
your Inspector class wrapper in the wrapper collection.

You can't rely on the first Activate with this method necessarily, or even
any Activate event firing at all initially (unless the user moves away from
the Inspector and back again to put focus on the Inspector window). I do
that using Win32 API functions.

I use FindWindow() to get the Outlook main window, set focus to that and
then set focus to the Inspector window to guarantee an Activate event.

I first use FindWindow("mspim_wnd32", "Microsoft Outlook") to get the HWND
of the Outlook window and the Inspector caption with the class "OpusApp" to
get the HWND of the Inspector window. Then I use SetActiveWindow() to shift
focus to Outlook and use SetActiveWindow() again to move focus back to the
Inspector window.




Hi, Ken:

Thanks for the idea, we're going to give timer a try. I wonder if you
could give some suggestion on:
1. What is the recommended timer interval?
2. Since our goal is to add a menu to New Mail window, I assume once
we find a Word Mail inspector, we'll use an inspector wrapper on it,
right? However, I think the inspector wrapper relies on the activate
event of the inspector to add the menu, if we use a timer, is it
possible that before we have a chance to add the inspector to wrapper,
the activate event is already fired? How do we handle this case?

Thanks

Jim
 
I tried it . But i can't compare two inspector objects. So i really replicate
it! Would you like to tell me how to compare them? Here is my code! It's
putted in a single thread ,not the main thread! I use sleep() so that it
works like a timer ! And i also try to use settimer(),but i can't compare two
objects either!

.......
struct Outlook::_Inspector* activeIn;
m_spApp->ActiveInspector(&activeIn);
if(NULL == activeIn)
continue;
CComPtr<IUnknown> activeUnk;
activeIn->QueryInterface(IID_IUnknown, (void**)&activeUnk);


struct Outlook::_Inspector* inspector;
CComPtr<IUnknown> spInspectUnk;
//IUnknown* spInspectUnk;

///*
for(long i=1;i<=nNowNum;i++)
{
inspectors->Item(CComVariant(i),&inspector);

if(NULL == inspector || 0xcccccccc == (long)inspector)
continue;

inspector->IsWordMail(&bWordMail);
if(!bWordMail)
continue;

inspector->QueryInterface(IID_IUnknown, (void**)&spInspectUnk);

if(spInspectUnk.IsEqualObject(activeUnk))
{
//dosomething
//how to come in this block
}
}
.........
 
Outlook 2007 implements the interface needed to be able to compare
Inspectors directly. Prior to that the only way really is to compare
properties on the 2 Inspectors. I use the window location and size, window
caption, and the EntryID of the item in the Inspector (null on unsaved
items). For checking WordMail I would use Inspector.CurrentItem.IsWordMail.

If you are running an Outlook COM addin you are running in-process with
Outlook and shouldn't use Sleep() and all Outlook references should run on
the main thread.
 
I use a timer to check the count of the inspector in the inspector collection
.. But i find that the count is always 0 in ol2000. Here is my code.

void __stdcall TimerFunc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
{
..........
struct Outlook::_Inspectors* inspectors;
pClass->m_spApp->get_Inspectors(&inspectors);
if(NULL == inspectors)
return;

inspectors->get_Count(&nNowNum);

struct Outlook::_Inspector* inspector;

for(int i=1;i<=nNowNum;i++)
{
inspectors->Item(CComVariant(i),&inspector);

if(NULL == inspector || 0xcccccccc == (long)inspector)
continue;

.......

}

......
}

Since the count is 0,i can't ge any inspector. Thankyou!
 
Ken Slovak - said:
Outlook 2007 implements the interface needed to be able to compare
Inspectors directly. Prior to that the only way really is to compare
properties on the 2 Inspectors. I use the window location and size, window
caption, and the EntryID of the item in the Inspector (null on unsaved
items). For checking WordMail I would use Inspector.CurrentItem.IsWordMail.

If you are running an Outlook COM addin you are running in-process with
Outlook and shouldn't use Sleep() and all Outlook references should run on
the main thread.
 
I've always seen the Count advance with WordMail.

What mode of Outlook 2000 are you using? Look in Help, About. It's possible
that Internet only mode doesn't increment Inspectors.Count with WordMail.
It's been so long since I tested with that mode that I don't recall.




xwjbs said:
I use a timer to check the count of the inspector in the inspector
collection
. But i find that the count is always 0 in ol2000. Here is my code.
<snip>
 
Heloo ken! There is another strange problem. I can't catch the invoke event
When I use "Send To Mail Recipient" . So I use a timer to check the count and
items of inspectors. It works fine. But when I close this window, it closed
but another window with all menus grayed exists and the outlook.exe process
doesn't exit. The follow is my code


if (idEvent != g_pAddIn->m_timerol2000)
return; ///*
CSecurityAddin* pClass=g_pAddIn;
VARIANT_BOOL bWordMail=false;

//static bActive = false;

struct Outlook::_Inspectors* pInspectors;
pClass->m_spApp->get_Inspectors(&pInspectors);
if(NULL == pInspectors)
return;

struct Outlook::_Inspector* pInspector;
long nIns=0;
pInspectors->get_Count(&nIns);
if(nIns<=0)
return;

if(g_bAdd)
return;
for(int i=1;i<=nIns;i++)
{
CComVariant vItem(i);
pInspectors->Item(vItem,&pInspector);
if(NULL != pInspector)// && !bActive)
{

#ifdef FIRSTDEBUG
fprintf(g_Log,"active!%d\n",i);
fflush(g_Log);
#endif
CInspectorWrapper* tmp = new CInspectorWrapper(pClass->m_spApp,pInspector);
tmp->attchMenu();
pClass->m_spInspectorNow.push_back(tmp);
g_bAdd = true;

}
}

I change it to thread but i can't resolve it either! I find that when i use
"pInspectors->Item(vItem,&pInspector);",this problem will occur. why? Thank
you very much
 
Are you releasing your Inspector wrapper class and any Inspector and item
objects when the Simple MAPI Inspector closes? What you are seeing sounds
like the "ghost" Inspector problem. That's a blank Inspector window that
cannot be closed using code but if the user clicks on the Close box in the
Inspector window the window does close. That happens with any modal
Inspector window (Simple MAPI Inspectors are opened modally) if you aren't
real careful to handle both the Inspector and item Close() events and don't
release all of your related objects in a timely fashion.
 
Back
Top