BUG: OnRead() Event Calls In Wrong Context When Opening Report Messages
ID: Q225009
|
The information in this article applies to:
-
Microsoft Outlook, versions 97, 98
SYMPTOMS
When your Microsoft Outlook extension is registered for the context "EECONTEXT_READNOTEMESSAGE", your extension is called when opening Report messages.
CAUSE
When Outlook opens a Report message for the first time, it also opens the original Note message internally to update it's tracking information. When this internal opening happens, it causes the OnRead() event to occur on it.
For example, lets say you have an extension registered for EECONTEXT_READNOTEMESSAGE and EECONTEXT_READREPORTMESSAGE. When you open a read receipt (Report message) for the first time, you will see the extension get called twice. First, it will get called for the report message(REPORT.IPM.Note.IPNRN), and immediately following this, it will get called for the original Note message(IPM.Note).
Note that after the tracking info has been updated from the first opening of the message, subsequent openings of the read receipt will not result in our IPM.Note being opened.
RESOLUTION
Typically, developers will not want the READ_NOTEMESSAGE extensions to be called when the user opens a report. To detect when your OnRead() is being called from within the OnRead() of a Report message, do the following:
- Register your extension to include EECONTEXT_READREPORTMESSAGE in addition to any other contexts you want.
- In your OnRead() code, add some logic to detect if the message being opened is of message class "REPORT.IPM.Note.IPNRN".
- If the message is a "REPORT>IPM.Note.IPNRN", you'll need to check if the property PR_PROCESSED has been set. This flag is set by Outlook the first time it opens a Report message. You will use it to determine if this is the first time the report has been opened. PR_PROCESSED is defined as:
#define PR_PROCESSED PROP_TAG( PT_BOOLEAN, 0x7D01)
- If PR_PROCESSED is not set or equals FALSE, you know it needs to ignore the next call to OnRead() as it will be the internal call from Outlook opening the original message.
#define PR_PROCESSED PROP_TAG( PT_BOOLEAN, 0x7D01)
STDMETHODIMP CExchExtMessageEvents::OnRead( LPEXCHEXTCALLBACK lpeecb )
{
LPMESSAGE pMessage=NULL;
LPMAPIPROP pPropObj=NULL;
LPSPropValue lpspvMsgClass = NULL;
LPSPropValue lpspvProcessed = NULL;
HRESULT hr = S_OK;
char sOut[256];
if(lpeecb->GetObject(NULL,&pPropObj)!=S_OK)
goto ret;
if(pPropObj->QueryInterface(IID_IMessage,(LPVOID *)&pMessage)!=S_OK)
goto ret;
hr = HrGetOneProp(pMessage, PR_MESSAGE_CLASS, &lpspvMsgClass);
sprintf(sOut, "Message Class = %s", lpspvMsgClass->Value.lpszA);
::MessageBox( NULL, sOut, "Message Class", MB_OK );
// Is this a report?
if(0 == strcmp("REPORT.IPM.Note.IPNRN", lpspvMsgClass->Value.lpszA))
{
// Has this report been processed before?
hr = HrGetOneProp(pMessage, PR_PROCESSED, &lpspvProcessed);
if(MAPI_E_NOT_FOUND == hr || !lpspvProcessed->Value.b)
{
::MessageBox( NULL, "This msg has NOT been Processed\n Ignore the next call to OnRead!", "Process State", MB_OK );
}
else
{
::MessageBox( NULL, "This Msg has already been Processed", "Process State", MB_OK );
}
}
ret:
if(pMessage) pMessage->Release();
if(pPropObj) pPropObj->Release();
if (lpspvMsgClass) MAPIFreeBuffer(lpspvMsgClass);
if (lpspvProcessed) MAPIFreeBuffer(lpspvProcessed);
return S_FALSE;
}
Note that if you want to be called when opening Report messages, you should register for the context "EECONTEXT_READREPORTMESSAGE")
STATUS
Microsoft has confirmed this to be a bug in the Microsoft products listed
at the beginning of this article.
Additional query words:
Keywords : kbEDK kbMsg kbOutlook kbOutlook97 kbOutlook98 kbVC kbGrpMsg kbDSupport
Version : WINDOWS:97,98
Platform : WINDOWS
Issue type : kbbug