<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Программирование для мобильных устройств &#187; MAPI</title>
	<atom:link href="http://mobile-developer.ru/category/mapi/feed/" rel="self" type="application/rss+xml" />
	<link>http://mobile-developer.ru</link>
	<description>Программирование для мобильных устройств. Разработка для Windows Mobile, Windows CE, Embedded Linux, Google Android, iPhone, Palm webOS и др. Все о программировании для мобильных телефонов, смартфонов, КПК и других мобильных устройств. Статьи, новости, руководства, видео уроки.</description>
	<lastBuildDate>Sun, 05 Sep 2010 20:40:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Программная отправка SMS на C++ с помощью CE MAPI</title>
		<link>http://mobile-developer.ru/wxwince/programmnaya-otpravka-sms-na-c-s-pomoshhyu-ce-mapi/</link>
		<comments>http://mobile-developer.ru/wxwince/programmnaya-otpravka-sms-na-c-s-pomoshhyu-ce-mapi/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 17:59:50 +0000</pubDate>
		<dc:creator>T-Rex</dc:creator>
				<category><![CDATA[MAPI]]></category>
		<category><![CDATA[wxWinCE]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[SMS]]></category>
		<category><![CDATA[Windows Mobile]]></category>
		<category><![CDATA[wxWidgets]]></category>

		<guid isPermaLink="false">http://mobile-developer.ru/?p=55</guid>
		<description><![CDATA[Появилась необходимость программно отправлять SMS с телефона под управлением Windows Mobile. Решил не изобретать велосипед и поиспользовать MAPI для этих целей. После недолгих поисков набрел на эту статью на CodeProject. Немного переделал код для использования с wxWidgets. Вот что получилось: wxSendSMS.h #ifndef _WX_SMS_SENDER_H #define _WX_SMS_SENDER_H #include &#60;wx/wx.h&#62; #include &#60;atlbase.h&#62; #include &#60;cemapi.h&#62; #include &#60;mapiutil.h&#62; class wxSMSSender [...]<p>Post from: <a href="http://mobile-developer.ru">Mobile-Developer.ru</a><br/><br/><a href="http://mobile-developer.ru/wxwince/programmnaya-otpravka-sms-na-c-s-pomoshhyu-ce-mapi/">Программная отправка SMS на C++ с помощью CE MAPI</a></p>
]]></description>
			<content:encoded><![CDATA[<a class="google_buzz"  
href="http://www.google.com/reader/link?url=http://mobile-developer.ru/wxwince/programmnaya-otpravka-sms-na-c-s-pomoshhyu-ce-mapi/&title=Программная+отправка+SMS+на+C+++с+помощью+CE+MAPI&srcURL=http://mobile-developer.ru" target="_blank" rel="nofollow"><img
src="http://mobile-developer.ru/wp-content/plugins/google-buzz-button-for-wordpress/images/google-buzz.png" alt="Google Buzz" /></a><p>Появилась необходимость программно отправлять SMS с телефона под управлением Windows Mobile. Решил не изобретать велосипед и поиспользовать MAPI для этих целей. После недолгих поисков набрел на эту <noindex><a rel="nofollow" href="http://mobile-developer.ru/goto/http://www.codeproject.com/KB/mobile/SMS_CEMPI.aspx" >статью</a></noindex> на CodeProject. Немного переделал код для использования с wxWidgets. Вот что получилось:<br />
<span id="more-55"></span><br />
<strong>wxSendSMS.h</strong></p>
<pre class="brush: cpp;">
#ifndef _WX_SMS_SENDER_H
#define _WX_SMS_SENDER_H

#include &lt;wx/wx.h&gt;
#include &lt;atlbase.h&gt;
#include &lt;cemapi.h&gt;
#include &lt;mapiutil.h&gt;

class wxSMSSender
{
public:
	virtual bool Send(const wxString &amp; from,
		const wxString &amp; to, const wxString &amp; text) = 0;
};

class wxSMSSenderMAPI : public wxSMSSender
{
	HRESULT GetSMSFolder(const CComPtr&lt;IMsgStore&gt;&amp; msgStore,
		CComPtr&lt;IMAPIFolder&gt;&amp; folder);
	HRESULT GetSMSMsgStore(const CComPtr&lt;IMAPISession&gt;&amp; session,
		CComPtr&lt;IMsgStore&gt;&amp; msgStore);
	HRESULT SendSMSMessage(const CComPtr&lt;IMAPISession&gt;&amp; session,
		LPCTSTR lpszFrom, LPCTSTR lpszTo, LPCTSTR lpszMessage);
public:
	virtual bool Send(const wxString &amp; from,
		const wxString &amp; to, const wxString &amp; text);
};

#endif
</pre>
<p><strong>wxSendSMS.cpp</strong></p>
<pre class="brush: cpp;">
#include &quot;wxSMSSender.h&quot;

HRESULT wxSMSSenderMAPI::GetSMSFolder(
			const CComPtr&lt;IMsgStore&gt;&amp; msgStore,
			CComPtr&lt;IMAPIFolder&gt;&amp; folder)
{
	// Now get the Drafts folder.
	SPropTagArray propDefaultFolder;
	propDefaultFolder.cValues = 1;
	propDefaultFolder.aulPropTag[0] = PR_CE_IPM_DRAFTS_ENTRYID;

	ULONG	values;
	LPSPropValue propVals;
	HRESULT hr = msgStore-&gt;GetProps(&amp;propDefaultFolder,
		MAPI_UNICODE, &amp;values, &amp;propVals);
	if (FAILED(hr))
	{
		return hr;
	}

	SBinary&amp; eidDrafts = propVals-&gt;Value.bin;

	hr = msgStore-&gt;OpenEntry(eidDrafts.cb, (LPENTRYID)eidDrafts.lpb,
		NULL, MAPI_MODIFY, NULL, (LPUNKNOWN*)&amp;folder);
	return hr;
}

HRESULT wxSMSSenderMAPI::GetSMSMsgStore(
			const CComPtr&lt;IMAPISession&gt;&amp; session,
			CComPtr&lt;IMsgStore&gt;&amp; msgStore)
{
	// first we get the msgstores table from the session
	CComPtr&lt;IMAPITable&gt; table;
	HRESULT hr = session-&gt;GetMsgStoresTable(MAPI_UNICODE, &amp;table);
	if (FAILED(hr))
	{
		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 = table-&gt;QueryRows(1, 0, &amp;pRowSet);

		// If we failed to query the
		// rows then we need to break
		if (FAILED(hr)) break;

		// if we got no rows back then just exit the loop
		//remembering to set an error
		if (pRowSet-&gt;cRows == 1)
		{
			ASSERT(pRowSet-&gt;aRow[0].lpProps-&gt;ulPropTag == PR_ENTRYID);
			SBinary&amp; blob = pRowSet-&gt;aRow[0].lpProps-&gt;Value.bin;
			hr = session-&gt;OpenMsgStore(NULL, blob.cb,
				(LPENTRYID)blob.lpb, NULL, 0, &amp;msgStore);
		}
		else
		{
			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 values;
		SPropValue* pProps = NULL;
		hr = msgStore-&gt;GetProps(&amp;props, MAPI_UNICODE, &amp;values, &amp;pProps);
		if (FAILED(hr) || values != 1)
		{
			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(&quot;SMS&quot;)) == 0)
		{
			break;
		}
	}

	// if we failed for some reason then we clear out
	// the msgstore smartpointer and return the error.
	if (FAILED(hr))
	{
		msgStore.Release();
	}

	return hr;
}

HRESULT wxSMSSenderMAPI::SendSMSMessage(const CComPtr&lt;IMAPISession&gt;&amp; session,
			LPCTSTR lpszFrom, LPCTSTR lpszTo, LPCTSTR lpszMessage)
{

	// now get the SMS message store
	CComPtr&lt;IMsgStore&gt; msgStore;
	HRESULT hr = GetSMSMsgStore(session, msgStore);
	if (FAILED(hr)) return hr;

	CComPtr&lt;IMAPIFolder&gt; folder;
	hr = GetSMSFolder(msgStore, folder);
	if (FAILED(hr)) return hr;

	CComPtr&lt;IMessage&gt; message;
	hr = folder-&gt;CreateMessage(NULL, 0 ,&amp;message);
	if (FAILED(hr)) 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(&amp;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(&quot;SMS&quot;);
	// 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)(&amp;propRecipient);

	// finally modify the recipients of the message
	hr = message-&gt;ModifyRecipients(MODRECIP_ADD, &amp;adrlist);
	if (FAILED(hr)) return hr;

	// 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(&amp;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 = message-&gt;SetProps(sizeof(props) / sizeof(SPropValue),
		(LPSPropValue)&amp;props, NULL);
	if (FAILED(hr)) return hr;

	// having set all the required fields we can now
	// pass the message over to the msgstore transport
	// to be delivered.
	hr = message-&gt;SubmitMessage(0);
	if (FAILED(hr)) return hr;

	return FALSE;
}

bool wxSMSSenderMAPI::Send(const wxString &amp; from,
		const wxString &amp; to, const wxString &amp; text)
{
	do
	{
		HRESULT hr = MAPIInitialize(NULL);
		if (FAILED(hr)) break;
		CComPtr&lt;IMAPISession&gt; mapiSession;
		hr = MAPILogonEx(0 ,NULL, NULL, 0, &amp;mapiSession);
		if (FAILED(hr)) break;
		bool result = SUCCEEDED(SendSMSMessage(mapiSession,
			from.GetData(), to.GetData(), text.GetData()));
		mapiSession-&gt;Logoff(0, 0, 0);
		mapiSession.Release();
		MAPIUninitialize();
		return result;
	}
	while(false);
	return false;
}
</pre>
<p>А пользоваться этим всем очень просто:</p>
<pre class="brush: cpp;">
wxSMSSenderMAPI sender;
if(!sender.Send(m_FromTextCtrl-&gt;GetValue(),
	m_ToTextCtrl-&gt;GetValue(), m_SMSTextCtrl-&gt;GetValue()))
{
	wxMessageBox(_(&quot;Не могу отправить SMS!&quot;));
}
</pre>
<p><a href="http://mobile-developer.ru/wp-content/uploads/2008/08/wxsendsms.7z" >Исходный код примера отправки SMS с помощью CE MAPI для Windows Mobile</a><br />
Скриншот тестового приложения:<br />
<a href="http://mobile-developer.ru/wp-content/uploads/2008/08/send_sms_with_ce_mapi_1.png" ><img src="http://mobile-developer.ru/wp-content/uploads/2008/08/send_sms_with_ce_mapi_1.png" alt="" title="Скриншот примера: Отправка SMS с помощью CE MAPI" width="329" height="527" class="aligncenter size-full wp-image-59" /></a></p>
<p>Post from: <a href="http://mobile-developer.ru" >Mobile-Developer.ru</a><br/><br/><a href="http://mobile-developer.ru/wxwince/programmnaya-otpravka-sms-na-c-s-pomoshhyu-ce-mapi/" >Программная отправка SMS на C++ с помощью CE MAPI</a></p>
]]></content:encoded>
			<wfw:commentRss>http://mobile-developer.ru/wxwince/programmnaya-otpravka-sms-na-c-s-pomoshhyu-ce-mapi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
