Inspector wrapper and Inspector::OnClose event

H

Henry Gusakovsky

Hi there,

I have problem with Inspector::OnClose event.
Add-in is written using VC++.
I add custom toolbars and advise Inspector events in the
OnNewInspector event.

void __stdcall CConnect::OnNewInspector(IDispatch
* /*Outlook::_Inspector**/ Ctrl)
{

USES_CONVERSION;

Outlook::_InspectorPtr pInspector(Ctrl);

CInspectorHandler * pInspectorHandler = new
CInspectorHandler( pInspector,m_lpSession, m_pAdrBook );



The problem is:
When user clicks SaveAndClose button Inspector::OnClose is
not fired. But if you press Ctrl-F4 or click on X in right
upper conner of the window this event fires.

To workaroud that problem I used Inspector::Deactivate
event. It fires always. In this event I check if current
ispector is in active inspectors collection via
Inspector.Application.Inspectors. I compare object
pointers. A peace of code:

BOOL FindInspectorInActiveInspectors( const
Outlook::_InspectorPtr & pInspector )
{
BOOL bFound = FALSE;

HRESULT hResult = S_OK;

Outlook::_ApplicationPtr pApplication;
Outlook::_InspectorsPtr pInspectors;
Outlook::_InspectorPtr pInspectorTemp;

hResult = pInspector->get_Application
(&pApplication);

if ( SUCCEEDED(hResult) )
{
hResult = pApplication->get_Inspectors
(&pInspectors);

if ( SUCCEEDED(hResult) )
{
LONG lCount = 0;
pInspectors->get_Count(&lCount);

for(LONG i = 1; i <= lCount; i++)
{
CComVariant varIndex(i);
hResult = pInspectors->Item
(varIndex,&pInspectorTemp);

if ( FAILED(hResult) )
break;

if( pInspectorTemp ==
pInspector)
{
bFound = TRUE;
break;
} // if
} // for

} // if

} // if


return bFound;
}
Outlook Objects are imported like:
#import "msoutl9.olb" rename_namespace("Outlook")
raw_interfaces_only named_guids

That aproach works in Outlook 2000 and in Outlook XP.
In Outlook 2003 i have a problem. When i change current
window (not closing it) Inspector::Deactivate comes. But i
don't not find current inspector in the inspectors
collection.

Using only inspector i found out:
Inspectors.Count == 1 but
address of the object i get via Inspectors.Item is
differ from my current inspector.

Some additional investigation says that
OOM for every Object return some sort of lightweight proxy
object
for example:

m_pApp is object passed in OnConnect event.
void __stdcall CConnect::OnNewInspector(IDispatch
* /*Outlook::_Inspector**/ Ctrl)
{
Outlook::_InspectorsPtr pInspectors;
Outlook::_InspectorPtr pInspector(Ctrl);
m_pApp->getInspectors(&pInspectors);

Outlook::_InspectorPtr pInspector1;
Outlook::_InspectorPtr pInspector2;
CComVariant varIndex(1);

pInspectors->Item(varIndex, pInspector1);
pInspectors->Item(varIndex, pInspector2);
//there address of object in the pInspector1
//differ from address of object in the pInspector2
}

As a result if i try to find current inspector in the
Inspectors collection I never find it.

I think that design change is because of improving
security model.

Any ideas how to workaround that problem.
I mean How to find current inspector in the inspectors
collection.

WBR
Henry
 
H

Henry Gusakovsky

I have some ideas how to workaround these problems:

1. Inspector::OnClose is not fired
check Inspector.CurrentItem in the OnDeactivate event
if CurrentItem is empty so Inspector is closed.

2. How to find current inspector in the inspectors
collection in Outlook 2003.
Obtain Inspector.CurrentItem.EntryID and compare
Items EntryIDs. I've noticed that Outlook never open
new Inspector for the same already opened Object.

So guys what do you think about it.
Any comments ?

WBR
Henry
Hi there,

I have problem with Inspector::OnClose event.
Add-in is written using VC++.
I add custom toolbars and advise Inspector events in the
OnNewInspector event.

void __stdcall CConnect::OnNewInspector(IDispatch
* /*Outlook::_Inspector**/ Ctrl)
{

USES_CONVERSION;

Outlook::_InspectorPtr pInspector(Ctrl);

CInspectorHandler * pInspectorHandler = new
CInspectorHandler( pInspector,m_lpSession, m_pAdrBook );



The problem is:
When user clicks SaveAndClose button Inspector::OnClose is
not fired. But if you press Ctrl-F4 or click on X in right
upper conner of the window this event fires.

To workaroud that problem I used Inspector::Deactivate
event. It fires always. In this event I check if current
ispector is in active inspectors collection via
Inspector.Application.Inspectors. I compare object
pointers. A peace of code:

BOOL FindInspectorInActiveInspectors( const
Outlook::_InspectorPtr & pInspector )
{
BOOL bFound = FALSE;

HRESULT hResult = S_OK;

Outlook::_ApplicationPtr pApplication;
Outlook::_InspectorsPtr pInspectors;
Outlook::_InspectorPtr pInspectorTemp;

hResult = pInspector->get_Application
(&pApplication);

if ( SUCCEEDED(hResult) )
{
hResult = pApplication->get_Inspectors
(&pInspectors);

if ( SUCCEEDED(hResult) )
{
LONG lCount = 0;
pInspectors->get_Count(&lCount);

for(LONG i = 1; i <= lCount; i++)
{
CComVariant varIndex(i);
hResult = pInspectors->Item
(varIndex,&pInspectorTemp);

if ( FAILED(hResult) )
break;

if( pInspectorTemp ==
pInspector)
{
bFound = TRUE;
break;
} // if
} // for

} // if

} // if


return bFound;
}
Outlook Objects are imported like:
#import "msoutl9.olb" rename_namespace("Outlook")
raw_interfaces_only named_guids

That aproach works in Outlook 2000 and in Outlook XP.
In Outlook 2003 i have a problem. When i change current
window (not closing it) Inspector::Deactivate comes. But i
don't not find current inspector in the inspectors
collection.

Using only inspector i found out:
Inspectors.Count == 1 but
address of the object i get via Inspectors.Item is
differ from my current inspector.

Some additional investigation says that
OOM for every Object return some sort of lightweight proxy
object
for example:

m_pApp is object passed in OnConnect event.
void __stdcall CConnect::OnNewInspector(IDispatch
* /*Outlook::_Inspector**/ Ctrl)
{
Outlook::_InspectorsPtr pInspectors;
Outlook::_InspectorPtr pInspector(Ctrl);
m_pApp->getInspectors(&pInspectors);

Outlook::_InspectorPtr pInspector1;
Outlook::_InspectorPtr pInspector2;
CComVariant varIndex(1);

pInspectors->Item(varIndex, pInspector1);
pInspectors->Item(varIndex, pInspector2);
//there address of object in the pInspector1
//differ from address of object in the pInspector2
}

As a result if i try to find current inspector in the
Inspectors collection I never find it.

I think that design change is because of improving
security model.

Any ideas how to workaround that problem.
I mean How to find current inspector in the inspectors
collection.

WBR
Henry
 
K

Ken Slovak - [MVP - Outlook]

If you compare ID's don't use a straight string comparison. MAPI ID's might
not be identical but still might map to the same object. Use something like
CDO 1.21's Session.CompareIDs method or the equivalent methods for
Redemption or Extended MAPI.
 

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