⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smshelper.cpp

📁 网上的通过CEMPAI来发送SMS邮件的实例
💻 CPP
字号:
#include "stdafx.h"
#include <atlbase.h>
#include <cemapi.h>
#include <mapiutil.h>
#include "resource.h"

/////////////////////////////////////////////////////////////////////////////////////////////
// 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))
	{
		AfxMessageBox(IDS_SMS_FAIL_MSGSTORE_TABLES);
		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))
		{
			AfxMessageBox(IDS_SMS_FAILEDTABLE);
			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))
				AfxMessageBox(IDS_SMS_FAILED_OPENMSGSTORE);

		}
		else
		{
			AfxMessageBox(IDS_SMS_MSGSTORENOTFOUND);
			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)
		{
			AfxMessageBox(IDS_SMS_FAILED_GETNAME);
			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;
}


/////////////////////////////////////////////////////////////////////////////////////////////
// This function is used to get the folder named drafts from the msgstore on the
// device.
// I could have used just raw pointers but it is much easier and safer to just 
// use smart pointers.
HRESULT GetSMSFolder(const CComPtr<IMsgStore>& spMsgStore, CComPtr<IMAPIFolder>& spFolder)
{
        // Now get the Drafts folder.
		SPropTagArray propDefaultFolder;
		propDefaultFolder.cValues = 1;
		propDefaultFolder.aulPropTag[0] = PR_CE_IPM_DRAFTS_ENTRYID;
		
		ULONG			cValues;
		LPSPropValue	pPropVals;
        HRESULT hr = spMsgStore->GetProps (&propDefaultFolder, MAPI_UNICODE, &cValues, &pPropVals);
        if (FAILED(hr))
		{
			AfxMessageBox(IDS_SMS_FOLDERNOTFOUND);
			return hr;
		}
    
		SBinary& eidDrafts = pPropVals->Value.bin;

        hr = spMsgStore->OpenEntry(eidDrafts.cb, (LPENTRYID)eidDrafts.lpb, NULL, MAPI_MODIFY, NULL, (LPUNKNOWN*)&spFolder);
		if (FAILED(hr))
		{
			AfxMessageBox(IDS_SMS_FOLDERNOTOPENED);
		}

		return hr;
}

/////////////////////////////////////////////////////////////////////////////////////////////
// This function is used to get the send the message.
// This uses an opened MAPI session
HRESULT SendSMSMessage(const CComPtr<IMAPISession>& spSession, LPCTSTR lpszFrom, LPCTSTR lpszTo, LPCTSTR lpszMessage)
{

	// now get the SMS message store
	CComPtr<IMsgStore> spMsgStore;
	HRESULT hr = GetSMSMsgStore(spSession, spMsgStore);
	if (FAILED(hr))
	{
		return hr;
	}

	CComPtr<IMAPIFolder> spFolder;

	hr = GetSMSFolder(spMsgStore, spFolder);
	if (FAILED(hr))
	{
		return hr;
	}

	CComPtr<IMessage> spMessage;
	hr = spFolder->CreateMessage(NULL, 0 ,&spMessage);
	if (FAILED(hr))
	{
		AfxMessageBox(IDS_SMS_FAIL_CREATEMESSAGE);
		return hr;
	}

	// set the recipients
	// set up the required fields for a recipient
	SPropValue propRecipient[3];
	// it is vital we clear the property structure
	// as there are fields we do not use but MAPI seems
	// to be sentative to them.
	ZeroMemory(&propRecipient, sizeof(propRecipient));
	// set the recipient type which coul be to, cc, bcc
	// but ehre must at least be a to field
	propRecipient[0].ulPropTag = PR_RECIPIENT_TYPE;
	propRecipient[0].Value.l = MAPI_TO;

	// we set the type of address to sms instead of
	// smtp
	propRecipient[1].ulPropTag = PR_ADDRTYPE;
	propRecipient[1].Value.lpszW = _T("SMS");
	// we finally set the email address to the
	// phone number of the person we are sending the message
	// to
	propRecipient[2].ulPropTag = PR_EMAIL_ADDRESS;
	propRecipient[2].Value.lpszW = (LPWSTR)lpszTo;

	// set the addrlist to point to the properties
	ADRLIST adrlist;
	adrlist.cEntries = 1;
	adrlist.aEntries[0].cValues = 3;
	adrlist.aEntries[0].rgPropVals = (LPSPropValue)(&propRecipient);

	// finally modify the recipients of the message
	hr = spMessage->ModifyRecipients(MODRECIP_ADD, &adrlist); 

	if (FAILED(hr))
	{
		AfxMessageBox(IDS_SMS_FAILED_ADDRECIPIENTS);
		return hr;
	}
	else
		; // added the recipient to the message

	// now we set the additional properties for the 
	// message
	SPropValue props[4];

	//note how we zero out the contents of the
	// structure as MAPI is sensative to the
	// contents of other fields we do not use.
	ZeroMemory(&props, sizeof(props));

	// first set the subject of the message
	// as the sms we are going to send
	props[0].ulPropTag = PR_SUBJECT;
	props[0].Value.lpszW = (LPWSTR)lpszMessage;

	// next set the senders email address to
	// the phone number of the person we are
	// sending the message to
	props[1].ulPropTag = PR_SENDER_EMAIL_ADDRESS;
	props[1].Value.lpszW = (LPWSTR)lpszFrom;

	// finally and most importantly tell mapi
	// this is a sms message in need of delivery
	props[2].ulPropTag = PR_MSG_STATUS;
	props[2].Value.ul = MSGSTATUS_RECTYPE_SMS;

    props[3].ulPropTag = PR_MESSAGE_FLAGS;
    props[3].Value.ul = MSGFLAG_FROMME | MSGFLAG_UNSENT;

	hr = spMessage->SetProps(sizeof(props) / sizeof(props[0]), (LPSPropValue)&props, NULL);
	if (FAILED(hr))
	{
		AfxMessageBox(IDS_SMS_FAIL_SETPROPS);
		return hr;
	}

	// having set all the required fields we can now
	// pass the message over to the msgstore transport
	// to be delivered.
	hr = spMessage->SubmitMessage(0);
	if (FAILED(hr))
	{
		AfxMessageBox(IDS_SMS_FAIL_SUBMITMSG);
		return hr;
	}

	return FALSE;
}

/////////////////////////////////////////////////////////////////////////
// This is the function that creates the session, using the
// from, the recipient and the message.
// This opens the session, opens the sms message store and opens
// the drafts folder then create a new message and sets the sender,
// recipient and messag, then finally sends the message.
BOOL DoSendMessage(LPCTSTR lpszFrom, LPCTSTR lpszTo, LPCTSTR lpszMessage)
{

	HRESULT hr = MAPIInitialize(NULL);
	if (FAILED(hr))
	{
		AfxMessageBox(IDS_SMS_FAIL_MAPIINIT);
		return hr;
	}
	else
	; // initialized the MAPI subsystem

	CComPtr<IMAPISession> spSession;

	BOOL bRet = FALSE;

	hr = MAPILogonEx(0 ,NULL, NULL, 0, &spSession);
	if (FAILED(hr))
	{
		AfxMessageBox(IDS_SMS_FAIL_MAPILOGON);
	}
	else
	{
		bRet = SUCCEEDED(SendSMSMessage(spSession, lpszFrom, lpszTo, lpszMessage));

		spSession->Logoff(0, 0, 0);

		spSession.Release();
	}

	MAPIUninitialize();

	return bRet;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -