none
Pocket Outlook Email Filter

    Question

  •  

    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.
    Wednesday, December 26, 2007 7:09 PM

All replies

  • 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 2

    Best regards,

    Guang-Ming Bian - MSFT

    Friday, December 28, 2007 9:11 AM
    Moderator
  • 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?

    Monday, December 31, 2007 1:24 PM