IMAPIAdviseSink -> Getting Notifications
Hey,
I recently had some problems with the IMAPIAdviseSink implementation that i made. It intercepts the messages sent from my program, but not from the rest of the OS. So if i send a message from the Messenger program, ill not get notified, but i will get notified if i send it from my own program. Why am i not receiving notification from the rest of the OS?
I was wondering if i forgot something. I am not to keen on all of the COM stuff so this is probably something i overlooked in the design.
Code Block
Code:
CComPtr<IMAPISession> spAdviceSession;
CComPtr<IMsgStore> spAdvMsgStore;
CComPtr<IMAPIFolder> spAdvFolder;
////////////////////////////////////////////////
//SMS OUTBOUND//////////////////////////////////
////////////////////////////////////////////////
class MAPIAdviseSink : public IMAPIAdviseSink
{
public:
MAPIAdviseSink();
virtual ULONG OnNotify(ULONG cNotif, LPNOTIFICATION lpNotifications);
virtual ULONG AddRef() { return ++refs; }
virtual HRESULT QueryInterface( REFIID iid, void ** ppvObject) { return E_NOTIMPL; }
virtual ULONG Release();
HRESULT prevResult;
private:
ULONG refs;
};
MAPIAdviseSink::MAPIAdviseSink(): refs(0)
{
}
ULONG MAPIAdviseSink::OnNotify(ULONG cNotif, LPNOTIFICATION lpNotifications)
{
return 0;
}
ULONG MAPIAdviseSink::Release()
{
return 0;
}
MAPIAdviseSink *AdviseSink = NULL;
/////////////////////////////////////////////////////////////////////////////////////////////
// This function is used to get the msgstore named SMS from msgstores on the
// device.
// I could have used just raw pointers but it is much easier and safer to just
// use smart pointers.
/////////////////////////////////////////////////////////////////////////////////////////////
HRESULT GetSMSMsgStore(const CComPtr<IMAPISession>& spSession, CComPtr<IMsgStore>& spMsgStore)
{
// first we get the msgstores table from the session
CComPtr<IMAPITable> spTable;
HRESULT hr = spSession->GetMsgStoresTable(MAPI_UNICODE, &spTable);
if (FAILED(hr))
{
MessageBox(0,_T("GetMsgStoresTable"),0,0);
return FALSE;
}
// next we loop over the message stores opening each msgstore and
// getting its name to see if the name matches SMS.
// If it does then we break out of the loop
while (TRUE)
{
SRowSet* pRowSet = NULL;
hr = spTable->QueryRows(1, 0, &pRowSet);
// If we failed to query the
// rows then we need to break
if (FAILED(hr))
{
MessageBox(0,_T("QueryRows"),0,0);
break;
}
// if we got no rows back then just exit the loop
//remembering to set an error
if (pRowSet->cRows == 1)
{
ASSERT(pRowSet->aRow[0].lpProps->ulPropTag == PR_ENTRYID);
SBinary& blob = pRowSet->aRow[0].lpProps->Value.bin;
hr = spSession->OpenMsgStore(NULL, blob.cb, (LPENTRYID)blob.lpb, NULL, 0, &spMsgStore);
if (FAILED(hr))
MessageBox(0,_T("OpenMsgStore"),0,0);
}
else
{
MessageBox(0,_T("MSGNOTFOUND"),0,0);
hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
}
// now remember to free the row set
FreeProws(pRowSet);
if (FAILED(hr))
{
break;
}
// now get the display name property from the
// message store to compare it against the name
// 'SMS'
SPropTagArray props;
props.cValues = 1;
props.aulPropTag[0] = PR_DISPLAY_NAME;
ULONG cValues;
SPropValue* pProps = NULL;
hr = spMsgStore->GetProps(&props, MAPI_UNICODE, &cValues, &pProps);
if (FAILED(hr) || cValues != 1)
{
MessageBox(0,_T("GetProps"),0,0);
break;
}
// if the name matches SMS then break and as
// hr == S_OK the current MsgStore smart pointer
// will correctly be set.
if (_tcsicmp(pProps[0].Value.lpszW, _T("SMS")) == 0)
{
break;
}
}
// if we failed for some reason then we clear out
// the msgstore smartpointer and return the error.
if (FAILED(hr))
{
spMsgStore.Release();
}
return hr;
}
BOOL DoSetAdviceSink()
{
HRESULT hr = MAPIInitialize(NULL);
if (FAILED(hr))
{
MessageBox(0,_T("MAPIInitialize"),0,0);
return hr;
}
else
; // initialized the MAPI subsystem
BOOL bRet = FALSE;
hr = MAPILogonEx(0 ,NULL, NULL, 0, &spAdviceSession);
if (FAILED(hr))
{
MessageBox(0,_T("MAPILogonEx"),0,0);
}
else
{
HRESULT hr = GetSMSMsgStore(spAdviceSession, spAdvMsgStore);
if (FAILED(hr))
{
MessageBox(0,_T("GetSMSMsgStore"),0,0);
return FALSE;
}
AdviseSink = new MAPIAdviseSink();
ULONG ulConn = 0;
spAdvMsgStore->Advise(0,NULL,fnevObjectCreated,AdviseSink,&ulConn);
}
return bRet;
}
BOOL DoUnsetAdviceSink()
{
spAdviceSession->Logoff(0, 0, 0);
spAdviceSession.Release();
MAPIUninitialize();
return TRUE;
}
Then i just call the DoSetAdviceSink from my program and thats it. Yeah i know about the Advice spelling error , i use it to differentiate diffrent Sinks that i have Big Smile
Thx in advance.