1. Fisrt Set the Following Class that process Notification
and you can re-write Function Code
ULONG MAPIAdviseSink::OnNotify(ULONG cNotif, LPNOTIFICATION lpNotifications)
run this Process when a new Message(Mail or SMS) or others operation flag you set.
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 *pAdviseSink;
MAPIAdviseSink::MAPIAdviseSink(): refs(0)
{
}
ULONG MAPIAdviseSink::OnNotify(ULONG cNotif, LPNOTIFICATION lpNotifications)
{
//ToDO: rewrite here...
AfxMessageBox(TEXT("new message in"));
/*********************************/
HRESULT hr;
ICEMAPISession * pSession = NULL;
hr = MAPIInitialize(NULL);
hr = MAPILogonEx(0, NULL, NULL, 0, (LPMAPISESSION *)&pSession);
/*****************************/
static const SizedSPropTagArray (2, spta) = { 2, PR_DISPLAY_NAME, PR_ENTRYID };
SRowSet *prowset = NULL;
CComPtr ptbl;
CComPtr pStore;
// Get the table of accounts
hr = pSession->GetMsgStoresTable(0, &ptbl);
// set the columns of the table we will query
hr = ptbl->SetColumns((SPropTagArray *) &spta, 0);
while (TRUE)
{
// Free the previous row
FreeProws (prowset);
prowset = NULL;
hr = ptbl->QueryRows (1, 0, &prowset);
if ((hr != S_OK) || (prowset == NULL) || (prowset->cRows == 0))
return -1;
ASSERT (prowset->aRow[0].cValues == spta.cValues);
SPropValue *pval = prowset->aRow[0].lpProps;
ASSERT (pval[0].ulPropTag == PR_DISPLAY_NAME);
ASSERT (pval[1].ulPropTag == PR_ENTRYID);
if (!_tcscmp(pval[0].Value.lpszW, TEXT("SMS")))
{
// Get the Message Store pointer
hr = pSession->OpenMsgStore(0, pval[1].Value.bin.cb, (LPENTRYID)pval[1].Value.bin.lpb, 0, 0, &pStore);
/**********************/
static const SizedSSortOrderSet(1, sortOrderSet) = { 1, 0, 0, { PR_MESSAGE_DELIVERY_TIME, TABLE_SORT_DESCEND } };
static const SizedSPropTagArray (3, spta) = { 3, PR_SENDER_NAME, PR_SUBJECT, PR_MESSAGE_DELIVERY_TIME };
HRESULT hr = S_OK;
LPENTRYID pEntryId = NULL;
ULONG cbEntryId = 0;
CComPtr pFolder;
CComPtr ptbl;
ULONG ulObjType = 0;
SRowSet *prowset = NULL;
// Get the inbox folder
hr = pStore->GetReceiveFolder(NULL, MAPI_UNICODE, &cbEntryId, &pEntryId, NULL);
// 2 we have the entryid of the inbox folder, let's get the folder and messages in it
hr = pStore->OpenEntry(cbEntryId, pEntryId, NULL, 0, &ulObjType, (LPUNKNOWN*)&pFolder);
// 3 From the IMAPIFolder pointer, obtain the table to the contents
hr = pFolder->GetContentsTable(0, &ptbl);
// 4 Sort the table that we obtained. This is determined by the sortOrderSet variable
hr = ptbl->SortTable((SSortOrderSet *)&sortOrderSet, 0);
// 5 Set the columns of the table we will query. The columns of each row are determined by spta
hr = ptbl->SetColumns ((SPropTagArray *) &spta, 0);
// now get first message in the table
// Free the previous row
FreeProws (prowset);
prowset = NULL;
hr = ptbl->QueryRows (1, 0, &prowset);
if ((hr != S_OK) || (prowset == NULL) || (prowset->cRows == 0))
return -1;
ASSERT (prowset->aRow[0].cValues == spta.cValues);
SPropValue *pval = prowset->aRow[0].lpProps;
// 6 Get the three properties we need: Sender name, Subject, and Delvery time.
ASSERT (pval[0].ulPropTag == PR_SENDER_NAME);
ASSERT (pval[1].ulPropTag == PR_SUBJECT);
ASSERT (pval[2].ulPropTag == PR_MESSAGE_DELIVERY_TIME);
LPCTSTR pszSender = pval[0].Value.lpszW;
LPCTSTR pszSubject = pval[1].Value.lpszW;
SYSTEMTIME st = {0};
FileTimeToSystemTime(&pval[2].Value.ft, &st);
// 7 Pass the parameters to a function to archive (this function is not written)
//hr = AppendToFile(pszFilename, pszSender, pszSubject, st);
AfxMessageBox(pszSubject);
/**********************/
}
}
/*****************************/
hr = pSession->Logoff(0, 0, 0);
pSession->Release();
pSession = NULL;
MAPIUninitialize();
/*********************************/
AfxMessageBox(lpNotifications->info.newmail.lpszMessageClass);
return 0;
}
ULONG MAPIAdviseSink::Release()
{
return 0;
}
2. the code following put on your main Program to set
what kinds of Notification that you want to Process.
you can modify operation flag at
hr = pStore->Advise(0, NULL, fnevObjectCreated | fnevNewMail | fnevObjectMoved | fnevObjectDeleted,pAdviseSink, &m_ulAdviseConnection);
for Example: the upper code we set opFlags when SMS Created, NewMail, Moved, Deleted
it will call MAPIAdviseSink::OnNotify to Process this new Message.
it is an Event-Driven Method.
HRESULT SaveMessages(IMsgStore *pStore, LPCTSTR pszFilename);
//HRESULT SaveSmsMessages(IMAPISession *pSession, LPCTSTR pszFilename);
HRESULT SaveSmsMessages(IMAPISession *pSession, LPCTSTR pszFilename)
{
static const SizedSPropTagArray (2, spta) = { 2, PR_DISPLAY_NAME, PR_ENTRYID };
HRESULT hr;
SRowSet *prowset = NULL;
CComPtr ptbl;
CComPtr pStore;
//---------------------
//IMAPIAdviseSink *pAdviseSink = NULL;
//ULONG m_ulAdviseConnection;
////HrThisThreadAdviseSink(new MyMsgStoreAdviseSink(),&msgStoreAdviseSink);
//hr = pSession->Advise(0, NULL, fnevNewMail | fnevObjectMoved , (LPMAPIADVISESINK)pAdviseSink, &m_ulAdviseConnection);
//
//if(hr == S_OK)
//{
// LPNOTIFICATION lpNotifications = NULL;
// ULONG res = pAdviseSink->OnNotify(0, lpNotifications);
// if(res != 0)
// AfxMessageBox(L"pAdviseSink->OnNotify FAIL");
// AfxMessageBox(L"pass");
// pAdviseSink->Release();
//}else{
// AfxMessageBox(L"pSession->Advise Fail");
//}
//---------------------
// Get the table of accounts
hr = pSession->GetMsgStoresTable(0, &ptbl);
//CHR(hr);
// set the columns of the table we will query
hr = ptbl->SetColumns((SPropTagArray *) &spta, 0);
//CHR(hr);
while (TRUE)
{
// Free the previous row
FreeProws (prowset);
prowset = NULL;
hr = ptbl->QueryRows (1, 0, &prowset);
if ((hr != S_OK) || (prowset == NULL) || (prowset->cRows == 0))
break;
ASSERT (prowset->aRow[0].cValues == spta.cValues);
SPropValue *pval = prowset->aRow[0].lpProps;
ASSERT (pval[0].ulPropTag == PR_DISPLAY_NAME);
ASSERT (pval[1].ulPropTag == PR_ENTRYID);
if (!_tcscmp(pval[0].Value.lpszW, TEXT("SMS")))
{
// Get the Message Store pointer
hr = pSession->OpenMsgStore(0, pval[1].Value.bin.cb, (LPENTRYID)pval[1].Value.bin.lpb, 0, 0, &pStore);
//CHR(hr);
//*************************************************
pAdviseSink = new MAPIAdviseSink();
ULONG m_ulAdviseConnection=0;
hr = pStore->Advise(0, NULL, fnevObjectCreated | fnevNewMail | fnevObjectMoved | fnevObjectDeleted,pAdviseSink, &m_ulAdviseConnection);
if(hr == S_OK)
{
}else{
AfxMessageBox(L"pSession->Advise Fail");
}
//*************************************************
//SaveMessages(pStore, pszFilename);
}
}
Error:
FreeProws (prowset);
return hr;
}
/*
HRESULT SaveMessages(IMsgStore *pStore, LPCTSTR pszFilename)
{
static const SizedSSortOrderSet(1, sortOrderSet) = { 1, 0, 0, { PR_MESSAGE_DELIVERY_TIME, TABLE_SORT_DESCEND } };
static const SizedSPropTagArray (3, spta) = { 3, PR_SENDER_NAME, PR_SUBJECT, PR_MESSAGE_DELIVERY_TIME };
HRESULT hr = S_OK;
LPENTRYID pEntryId = NULL;
ULONG cbEntryId = 0;
CComPtr pFolder;
CComPtr ptbl;
ULONG ulObjType = 0;
SRowSet *prowset = NULL;
// 1 First retrieve the ENTRYID of the Inbox folder of the message store
// Get the inbox folder
hr = pStore->GetReceiveFolder(NULL, MAPI_UNICODE, &cbEntryId, &pEntryId, NULL);
//CHR(hr);
// 2 we have the entryid of the inbox folder, let's get the folder and messages in it
hr = pStore->OpenEntry(cbEntryId, pEntryId, NULL, 0, &ulObjType, (LPUNKNOWN*)&pFolder);
//CHR(hr);
ASSERT(ulObjType == MAPI_FOLDER);
// 3 From the IMAPIFolder pointer, obtain the table to the contents
hr = pFolder->GetContentsTable(0, &ptbl);
//CHR(hr);
// 4 Sort the table that we obtained. This is determined by the sortOrderSet variable
hr = ptbl->SortTable((SSortOrderSet *)&sortOrderSet, 0);
//CHR(hr);
// 5 Set the columns of the table we will query. The columns of each row are determined by spta
hr = ptbl->SetColumns ((SPropTagArray *) &spta, 0);
//CHR(hr);
// now iterate through each message in the table
while (TRUE)
{
// Free the previous row
FreeProws (prowset);
prowset = NULL;
hr = ptbl->QueryRows (1, 0, &prowset);
if ((hr != S_OK) || (prowset == NULL) || (prowset->cRows == 0))
break;
ASSERT (prowset->aRow[0].cValues == spta.cValues);
SPropValue *pval = prowset->aRow[0].lpProps;
// 6 Get the three properties we need: Sender name, Subject, and Delvery time.
ASSERT (pval[0].ulPropTag == PR_SENDER_NAME);
ASSERT (pval[1].ulPropTag == PR_SUBJECT);
ASSERT (pval[2].ulPropTag == PR_MESSAGE_DELIVERY_TIME);
LPCTSTR pszSender = pval[0].Value.lpszW;
LPCTSTR pszSubject = pval[1].Value.lpszW;
SYSTEMTIME st = {0};
FileTimeToSystemTime(&pval[2].Value.ft, &st);
// 7 Pass the parameters to a function to archive (this function is not written)
//hr = AppendToFile(pszFilename, pszSender, pszSubject, st);
//AfxMessageBox(pszFilename);
//AfxMessageBox(pszSender);
AfxMessageBox(pszSubject);
//CHR(hr);
}
Error:
FreeProws (prowset);
MAPIFreeBuffer(pEntryId);
return hr;
}
*/
void CSYDlg::OnBnClickedButton1()
{
HRESULT hr;
ICEMAPISession * pSession = NULL;
hr = MAPIInitialize(NULL);
hr = MAPILogonEx(0, NULL, NULL, 0, (LPMAPISESSION *)&pSession);
SaveSmsMessages(pSession, L"TestFileName");
hr = pSession->Logoff(0, 0, 0);
pSession->Release();
pSession = NULL;
}
if you want to know Read SMS can ref: mobile read sms 透過MAPI
it tell WHY you can not use SMSOPEN(...) to get incoming Message