Pocket Outlook Email Filter
-
Wednesday, December 26, 2007 7:09 PM
Hi, I'm trying to develop an application closely combined with Pocket Outlook. I have a few questions regarding that. If any of them is already answered please point me to that. Here are my questions.
1. A filter should receive the emails before it reaches the Inbox. Extracts email details as-well-as all the attachments, targeted for a specific email ID. Block the required email to reach the Inbox.
2. Generate the default email-receive notification (Sound+Light+Vibrate combination depending upon the profile).
3. Create and put the email, along with attachment in the Outbox.
4. Get notified when an email is sent and moved to sent items folder.
5. Delete emails from Outbox, sent Items folder.
If (worst case) 1 and 2 above are not possible, is there any way to get events/callback when a new email reaches the Inbox and programmatically move it from the Inbox.
An additional question:
Is there any way to know, from the received email, the sequence in which the attachments were attached in the original email?
Thanks in advance.
All Replies
-
Friday, December 28, 2007 9:11 AMModerator
Hi Kausikd,
You can use CEMAPI, which implement IMAPIAdviseSink that listens to any events occurred to a mail store.
Click below link to get sample:
http://support.microsoft.com/default.aspx?scid=kb;en-us;230770
For delete and create a mail, you will open related email message stores , then do some operating:
Fore more information, click the link below:
Introduction to MAPI in Pocket PC 2002 C++ Applications, Part 1
Introduction to MAPI in Pocket PC 2002 C++ Applications, Part 2Best regards,
Guang-Ming Bian - MSFT
-
Monday, December 31, 2007 1:24 PM
Hi Thanks for the reply. As per your advice, I've downloaded the code from http://support.microsoft.com/default.aspx?scid=kb;en-us;230770 and able to run in XP. The application is nicely getting notifications.
BUT I need the application to run in WinCE. So after putting a terrific effort, I could decode the flow of the code and developed the wince replication. I am attaching my code here.
Code Block//A helper class to register the sync handler to MAPI. The header file
#ifndef
__SYNCHELPER_H__#define
__SYNCHELPER_H__
#include <cemapi.h>#include
<atlbase.h>#include
<mapiutil.h>#include
<vector>typedef
struct{
IMsgStore *m_sMsgStore;
ULONG m_sAdviceConnection;
LPMAPIFOLDER m_sFolderHandle;
ULONG m_sSizeEntryID;
LPENTRYID m_sEntryIDPtr;
LPMAPITABLE m_sTablePtr;
} MessageStoreDetails;
class
SyncHelper{
protected
:IMAPISession *m_cMapiSession;
std::vector<MessageStoreDetails> m_cMsgStorePtrs;
public
:SyncHelper();
~SyncHelper();
BOOL RemoveAdviceSink();
HRESULT AddAdviceSink(LPNOTIFCALLBACK pFnCallback,LPVOID pContext, LPMAPIADVISESINK* pAdviseSinkPtr);
private
:HRESULT AddSyncInMsgStores(LPMAPIADVISESINK pSyncPtr);
HRESULT HrAllocAdviseSink(LPNOTIFCALLBACK pFnCallback,LPVOID pContext, LPMAPIADVISESINK* pAdviseSinkPtr);
};
#endif
//__SYNCHELPER_H__Code Block//A helper class to register the sync handler to MAPI. The Cpp file
#include
"SyncHelper.h"#define
INITGUID#define
USES_IID_IMAPIAdviseSink#include
<initguid.h>#include
<mapiguid.h>#pragma
comment(lib,"cemapi.lib")SyncHelper::SyncHelper()
{
m_cMapiSession = NULL;
}
SyncHelper::~SyncHelper()
{
RemoveAdviceSink();
}
STDAPI SyncHelper::HrAllocAdviseSink(LPNOTIFCALLBACK pFnCallback,LPVOID pContext, LPMAPIADVISESINK* pAdviseSinkPtr)
{
HRESULT lRetVal = S_OK;
if( NULL == pAdviseSinkPtr )
lRetVal = E_INVALIDARG;
else
{
*pAdviseSinkPtr = new CInboxSyncCallBack( pFnCallback, pContext );
if( NULL == *pAdviseSinkPtr )
lRetVal = E_OUTOFMEMORY;
else
(*pAdviseSinkPtr)->AddRef();
}
return lRetVal;
}
HRESULT SyncHelper::AddSyncInMsgStores(LPMAPIADVISESINK pSyncPtr)
{
IMAPITable *lTablePtr = NULL;
SRowSet *lRowSet = NULL;
SPropTagArray lPropTag = {0};
ULONG lValues = 0;
SPropValue *lPropValue = NULL;
IMsgStore *lMsgStore = NULL;
bool lContStore = true;
// Get the message stores table
HRESULT lHRes = m_cMapiSession->GetMsgStoresTable(MAPI_UNICODE, &lTablePtr);
if (SUCCEEDED(lHRes))
{
lHRes = lTablePtr->QueryRows(1, 0, &lRowSet);
while(SUCCEEDED(lHRes))
{
if (lRowSet->cRows == 1)
{
if ((1 > lRowSet->aRow[0].cValues)||(PR_ENTRYID != lRowSet->aRow[0].lpProps[0].ulPropTag))
lHRes = E_FAIL;
else
lHRes = m_cMapiSession->OpenMsgStore(NULL,
lRowSet->aRow[0].lpProps->Value.bin.cb,
(LPENTRYID)lRowSet->aRow[0].lpProps->Value.bin.lpb,
NULL,
0,
&lMsgStore);
}
else
lContStore = false;
FreeProws(lRowSet);
if(SUCCEEDED(lHRes) && true == lContStore)
{
lPropTag.cValues = 2;
lPropTag.aulPropTag[0] = PR_DISPLAY_NAME;
lPropTag.aulPropTag[1] = PR_CE_IPM_INBOX_ENTRYID;
lHRes = lMsgStore->GetProps(&lPropTag, MAPI_UNICODE, &lValues, &lPropValue);
if (SUCCEEDED(lHRes) && lValues == 2)
{
//I do not know if there is any other better way to do this
if ((_tcsicmp(lPropValue[0].Value.lpszW, _T("SMS")) != 0
&& _tcsicmp(lPropValue[0].Value.lpszW, _T("MMS")) != 0
&& _tcsicmp(lPropValue[0].Value.lpszW, _T("ActiveSync")) != 0)
&& lPropValue[1].ulPropTag == PR_CE_IPM_INBOX_ENTRYID)
{
MessageStoreDetails lEachStore = {0};
lMsgStore->GetReceiveFolder(NULL,MAPI_UNICODE,&lEachStore.m_sSizeEntryID,&lEachStore.m_sEntryIDPtr,NULL);
lHRes = lMsgStore->OpenEntry(lPropValue[1].Value.bin.cb,
(LPENTRYID)lPropValue[1].Value.bin.lpb,
NULL,
MAPI_BEST_ACCESS,
NULL,
reinterpret_cast <IUnknown **>(&lEachStore.m_sFolderHandle));
if(SUCCEEDED(lHRes))
{
//If the following block is unblocked I get the lHRes = E_NOTIMPL, So I am "Advicing" on lMsgStore
/*
lEachStore.m_sFolderHandle->GetContentsTable(0,&lEachStore.m_sTablePtr);
if(NULL != lEachStore.m_sTablePtr)
lHRes = lEachStore.m_sTablePtr->Advise(fnevTableModified,pSyncPtr,&lEachStore.m_sAdviceConnection);*/
lHRes = lMsgStore->Advise(0,NULL,fnevObjectCreated | fnevNewMail | fnevTableModified,pSyncPtr,&lEachStore.m_sAdviceConnection);
if(SUCCEEDED(lHRes))
{
lEachStore.m_sMsgStore = lMsgStore;
m_cMsgStorePtrs.insert(m_cMsgStorePtrs.end(),lEachStore);
}
else
break;
}
else
break;
}
}
else
{
lMsgStore->Release();
lMsgStore = NULL;
}
if(NULL != lPropValue)
MAPIFreeBuffer(lPropValue);
lPropValue = NULL;
}
else
break
;lHRes = lTablePtr->QueryRows(1, 0, &lRowSet);
}
}
if(NULL != lPropValue)
{
MAPIFreeBuffer(lPropValue);
lPropValue = NULL;
}
return lHRes;
}
HRESULT SyncHelper::AddAdviceSink(LPNOTIFCALLBACK pFnCallback,LPVOID pContext, LPMAPIADVISESINK* pAdviseSinkPtr)
{
HRESULT lHRes = MAPIInitialize(NULL);
if(SUCCEEDED(lHRes))
{
lHRes = MAPILogonEx(0 ,NULL, NULL, 0, &m_cMapiSession);
lHRes = HrAllocAdviseSink( pFnCallback, pContext, pAdviseSinkPtr );
if(SUCCEEDED(lHRes))
lHRes = AddSyncInMsgStores(*pAdviseSinkPtr);
}
if(!SUCCEEDED(lHRes))
RemoveAdviceSink();
return lHRes;
}
BOOL SyncHelper::RemoveAdviceSink()
{
//Do the necessary cleanup
if(NULL != m_cMapiSession){
m_cMapiSession->Logoff(0, 0, 0);
m_cMapiSession->Release();
}
m_cMapiSession = NULL;
MAPIUninitialize();
return TRUE;
}
I've defined a simple Sync handler as described in http://msdn2.microsoft.com/en-us/library/ms531697.aspx and am waiting on a break point in OnNotify. My Application is not getting any event. I tried with:
1. Email is received
2. Email deleted.
3. Folder created.
4. Folder deleted.
As per MSDN the "Advice" methos id not implemented in WinCE for IMAPITable interface.
Can tell me where I'm wrong?

