在开始之前,需要说明的是,本文不适用于Windows CE智能手机设备。现在已经明确了这一点,本文将展示如何使用Windows CE消息应用程序接口(MAPI API,也称为CEMAPI)而不是提供的短信API,向另一个短信设备发送短信。
短信(SMS)或简单消息服务是一种通过GSM网络向另一个短信设备发送短消息(最多160个字符)的方式。在Pocket PC Phone版设备和Windows CE智能手机上,选择文件夹时,至少应该有一个ActiveSync和短信消息存储,可能还有一个彩信消息存储。
这些消息存储在设备上本地保存来自不同传输提供商的消息。
为了本文的目的,将专注于短信消息存储,因为想使用它来发送消息。
为了使代码更简单、更易于理解,大部分代码使用MFC进行用户界面设计,使用ATL进行智能指针支持。如果有人请求,可能会提供一个Win32版本,因为相关代码(即,不是UI代码)只需要ATL而不是MFC。
在本文中,不会详细列出创建MAPI会话和打开短信消息存储和发件箱文件夹的过程。代码有很好的注释,并在源代码zip文件中的两个函数GetSMSMsgStore和GetSMSFolder中提供,这些函数获取相关的短信消息存储和短信草稿文件夹。
所以开始查看代码时,已经在发件箱文件夹中创建了新消息。
大部分代码涉及创建收件人并设置发件人和消息状态。首先是设置消息的收件人。为了使代码更清晰,只为消息设置了一名收件人,尽管可以设置多个收件人,每个收件人都需要三个属性:收件人类型、地址类型和电子邮件地址。
不幸的是,发现微软提供的MAPI示例代码过于复杂,因为它们被过于复杂的内存和指针操作所掩盖。因此,提供了一个更简单的收件人实现。
SPropValue propRecipient[3];
ZeroMemory(&propRecipient, sizeof(propRecipient));
// 设置收件人类型,可以是to, cc, bcc
// 但至少需要一个to字段
propRecipient[0].ulPropTag = PR_RECIPIENT_TYPE;
propRecipient[0].Value.l = MAPI_TO;
propRecipient[1].ulPropTag = PR_ADDRTYPE;
propRecipient[1].Value.lpszW = _T("SMS");
propRecipient[2].ulPropTag = PR_EMAIL_ADDRESS;
propRecipient[2].Value.lpszW = (LPWSTR)lpszTo;
如果想向消息添加额外的收件人,可以将propRecipient扩展到三的倍数,并添加相应的收件人类型、地址类型和地址属性。
接下来,需要设置ADRLIST结构,使其指向收件人属性和属性计数。需要为每个收件人提供一个ADRENTRY。
ADRLIST adrlist;
adrlist.cEntries = 1;
adrlist.aEntries[0].cValues = 3;
adrlist.aEntries[0].rgPropVals = (LPSPropValue)(&propRecipient);
最后,修改消息的收件人。
hr = spMessage->ModifyRecipients(MODRECIP_ADD, &adrlist);
接下来,将消息主题设置为要发送的短信正文。请注意,短信消息的长度不能超过160个字符,因为这是使用GSM短消息服务可以发送的消息的最大大小。
最后,设置其余的属性,这些属性是发件人作为消息的发起人,以及将消息记录类型设置为SMS,以便它被传输并正确发送。可选地,可以设置消息标志,指示消息未发送且来自。
SPropValue props[4];
ZeroMemory(&props, sizeof(props));
// 设置主题
props[0].ulPropTag = PR_SUBJECT;
props[0].Value.lpszW = (LPWSTR)lpszMessage;
// 设置发件人
props[1].ulPropTag = PR_SENDER_EMAIL_ADDRESS;
props[1].Value.lpszW = (LPWSTR)lpszFrom;
// 设置消息状态以指示此消息需要枚举。重要属性!
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);
现在所有属性和收件人都已设置在消息上,可以安全地调用SubmitMessage了。
// 将新消息提交到消息存储,以便它可以被提交到适当的消息传输提供商。
hr = spMessage->SubmitMessage(0);
如果等待几秒钟,消息将出现在在消息的To字段中指定的电话号码上。同样请注意,发送的消息现在将出现在已发送项目文件夹中,正如所期望的。
目前没有在这里包含Win32或SmartPhone版本的代码。然而,如果有人想要这些版本,请给发电子邮件,会考虑更新示例以包括SmartPhone和纯Win32版本。