4362
- 收藏
- 点赞
- 分享
- 举报
CEMAPI操作信箱中的短信息(上)
三.操作信箱中的短信息
1. Windows mobile中短消息的组成
用过的Windows Mobile平台设备的朋友在第一次发送的短信的时候或多或少都会有些困惑,尤其是使用Windows Mobile 2003以前版本的朋友,发短信的UI上不但有填写目的号码和正文的地方,还有填写主题,CC甚至BCC的位置,搞得用户不知如何是好。为什么会有这些内容前面实际上已经提到过了。WM系统中邮件和短消息属于一个系统,微软为了开发方便将二者使用了相同的架构和接口,因此才会有短消息中存在CC和BCC这样的事情出现。虽然从WM5.0以后的版本开始,主题,CC,BCC等东西已经不见了,但是为了后面方便阐述解析原始短信息部分内容,这里简单的说一下短信的结构组成。
CC,BCC这些内容是发送短信中不需要的,填写了也没有什么效果。但是主题(subject)如果填写了是会对短信内容产生影响的。MSDN上介绍,如果发送短信的时候在主题和正文(Body)中都填写了内容,那么发送时,系统会在主题的内容后增加一个换行符,然后在把正文添加到后面作为短信真正的正文发送出去。注意WM中的换行符是\n而不是\r\n。除了主题和正文以外,一条短息还包括发送时间,接收时间,发送方号码,接受方号码等属性组成。在某一条具体信息之中这些属性不一定同时存在,对于不同具体信箱(Folder)中的短信息,拥有不同的属性。例如:收件箱中的短信,只有正文、发送方号码、发送时间这几个属性。
2. IMessage接口
前面对短信的结构做了一个简要的了解,现在要介绍一个与短信相关的非常重要的接口,IMessage接口。该接口直接继承自IMAPIProp,有IMAPIProp间接继承自IUnknow接口,同样属于COM对象。接口中封装了与短信相关的基本操作,常用的方法,例如Get/SetProps、SubMessage、SaveChange等方法是值得大家去特别注意的,这些方法的用法,后面会提到。
3. SizedSPropTagArray宏
上一部分中我们已经介绍过SizedSPropTagArray宏以及用它动态生成结构体类型的方法,这里再强调一下,这个宏在cemapi中非常重要,希望大家能够关注。关于这个宏的使用方法,请参见上一部分的内容。
4. 从具体信箱中获取一条原始短消息
上一部分中已经详细的讨论了如何建立与短信邮件系统的会话(Session),如何获取短信仓库(MsgStore)以及如何与具体的信箱(Folder)进行连接。我们先来简单回顾一下,首先利用MAPILogonEx函数建立与短信邮件系统的会话,然后利用IMAPISession接口的对象获取所有消息(邮件)仓库(MsgStore),遍历这些仓库,根据PR_DISPLAY_NAME属性的值获取短信所对应的短信仓库对象。然后根据具体信箱对应的参数获取指向具体信箱的对象(Folder)。
有了具体的信箱以后,下面需要做的就是要从该信箱中获取一条原始短消息了,原始短消息由Imessage接口对应的对象表示。前面说过,Cemapi中无论是短信(邮件)仓库MsgStore,还是具体信箱(Folder)均是由表格的形式表示的,Folder中的短信自然也不例外。我们可以通过GetContentsTable方法来获取信息对应的表格对象IMAPITable。如果大家忘记了,可以返回上一部分再看一下。GetContentsTable方法声明如下:
HRESULT IMAPIFolder::GetContentsTable(ULONG,IMAPITable **);
方法的返回值用于判断方法是否执行正确。参数列表:
ULONG:很抱歉,这个参数我没有看到过相关的介绍,在我们的应用中赋值为0是可以正常工作的。
IMAPITable **:用于返回短信列表对应的表结构。
我认为Cemapi中有一个原则(你可以不这么认为),只要出现了IMAPITable接口的对象,就需要采用SizePropTagArray这个宏来声明一个动态结构体,并且调用SetColumns告诉IMAPITable接口对象,列表中的行记录的组织结构。现在我们需要获取行记录中的ENTRYID,然后用这个ENTRYID去Folder中获取对应的短信息对象。
SizedSPropTagArray(1, Columns) = //动态生成结构体对象,只获取Entry ID属性
{
1,
PR_ENTRYID
};
还记得这么声明的意义吗?我们声明了一个动态结构体变量Columns,该结构体中的ULONG值为1(表示数组元素数量),ULONG数组共一个元素,名为PR_ENTRYID。有了这个结构体以后,采用SetColumns方法就可以对表格中行记录结构进行设置了。源代码如下:
IMAPITable *m_pTable = NULL;
m_pFolder->GetContentsTable(0, &m_pTable); //获取该Box下的短信行记录列表
hr = m_pTable->SetColumns((LPSPropTagArray)&Columns, 0); //设置列格式
行记录结构设置完毕以后,与获取MsgStore对象类似,使用QueryRows方法就可以获取该表中所有的行记录了。获取每一行的ENTRYID属性,然后使用IMAPIFolder中的OpenEntry方法(很熟悉吧,没错,就是与获取MsgStore时ImsgStore中的同名方法相同)来获取EntryId对应的短消息了。
获取原始短消息的代码如下:
LPMAPITABLE m_pTable = NULL;
LPSRowSet m_pRows = NULL;
HRESULT hr;
SizedSPropTagArray(1, Columns) = //动态生成结构体对象,只获取Entry ID属性
{
1,
PR_ENTRYID
};
m_pFolder->GetContentsTable(0, &m_pTable); //获取该Box下的内容列表
hr = m_pTable->SetColumns((LPSPropTagArray)&Columns, 0); //设置列记录结构
if(FAILED(hr))
{
//异常处理
}
ULONG ulRowCount=0;
ULONG i=0;
m_pTable->GetRowCount(0,&ulRowCount); //获取列表中行记录总数
while(!FAILED(m_pTable->QueryRows(1, 0, &m_pRows)))
{
if(i==ulRowCount) break; //如果已经遍历完毕
else i++;
IMessage *m_pMsg = NULL;
ULONG ulMesageType;
//通过OpenEntry获取IMessage对象
hr=m_pFolder->OpenEntry( m_pRows->aRow[0].lpProps[0].Value.bin.cb,
(LPENTRYID)m_pRows->aRow[0].lpProps[0].Value.bin.lpb,
NULL,
MAPI_BEST_ACCESS,
&ulMesageType,
(LPUNKNOWN*)&m_pMsg);
if(!FAILED(hr) && NULL!=m_pMsg) //取到了消息
{
//取到了原始消息
}
if(m_pRows)
{
FreemProws(m_pRows); //释放行
m_pRows=NULL;
}
}
if(m_pTable)
{
m_pTable->Release(); //释放表结构
m_pTable=NULL;
}
5.释放IMessage对象.
使用IMessage::Release()方法,可以安全的释放该对象。代码如下:
m_pMsg->Release();
1. Windows mobile中短消息的组成
用过的Windows Mobile平台设备的朋友在第一次发送的短信的时候或多或少都会有些困惑,尤其是使用Windows Mobile 2003以前版本的朋友,发短信的UI上不但有填写目的号码和正文的地方,还有填写主题,CC甚至BCC的位置,搞得用户不知如何是好。为什么会有这些内容前面实际上已经提到过了。WM系统中邮件和短消息属于一个系统,微软为了开发方便将二者使用了相同的架构和接口,因此才会有短消息中存在CC和BCC这样的事情出现。虽然从WM5.0以后的版本开始,主题,CC,BCC等东西已经不见了,但是为了后面方便阐述解析原始短信息部分内容,这里简单的说一下短信的结构组成。
CC,BCC这些内容是发送短信中不需要的,填写了也没有什么效果。但是主题(subject)如果填写了是会对短信内容产生影响的。MSDN上介绍,如果发送短信的时候在主题和正文(Body)中都填写了内容,那么发送时,系统会在主题的内容后增加一个换行符,然后在把正文添加到后面作为短信真正的正文发送出去。注意WM中的换行符是\n而不是\r\n。除了主题和正文以外,一条短息还包括发送时间,接收时间,发送方号码,接受方号码等属性组成。在某一条具体信息之中这些属性不一定同时存在,对于不同具体信箱(Folder)中的短信息,拥有不同的属性。例如:收件箱中的短信,只有正文、发送方号码、发送时间这几个属性。
2. IMessage接口
前面对短信的结构做了一个简要的了解,现在要介绍一个与短信相关的非常重要的接口,IMessage接口。该接口直接继承自IMAPIProp,有IMAPIProp间接继承自IUnknow接口,同样属于COM对象。接口中封装了与短信相关的基本操作,常用的方法,例如Get/SetProps、SubMessage、SaveChange等方法是值得大家去特别注意的,这些方法的用法,后面会提到。
3. SizedSPropTagArray宏
上一部分中我们已经介绍过SizedSPropTagArray宏以及用它动态生成结构体类型的方法,这里再强调一下,这个宏在cemapi中非常重要,希望大家能够关注。关于这个宏的使用方法,请参见上一部分的内容。
4. 从具体信箱中获取一条原始短消息
上一部分中已经详细的讨论了如何建立与短信邮件系统的会话(Session),如何获取短信仓库(MsgStore)以及如何与具体的信箱(Folder)进行连接。我们先来简单回顾一下,首先利用MAPILogonEx函数建立与短信邮件系统的会话,然后利用IMAPISession接口的对象获取所有消息(邮件)仓库(MsgStore),遍历这些仓库,根据PR_DISPLAY_NAME属性的值获取短信所对应的短信仓库对象。然后根据具体信箱对应的参数获取指向具体信箱的对象(Folder)。
有了具体的信箱以后,下面需要做的就是要从该信箱中获取一条原始短消息了,原始短消息由Imessage接口对应的对象表示。前面说过,Cemapi中无论是短信(邮件)仓库MsgStore,还是具体信箱(Folder)均是由表格的形式表示的,Folder中的短信自然也不例外。我们可以通过GetContentsTable方法来获取信息对应的表格对象IMAPITable。如果大家忘记了,可以返回上一部分再看一下。GetContentsTable方法声明如下:
HRESULT IMAPIFolder::GetContentsTable(ULONG,IMAPITable **);
方法的返回值用于判断方法是否执行正确。参数列表:
ULONG:很抱歉,这个参数我没有看到过相关的介绍,在我们的应用中赋值为0是可以正常工作的。
IMAPITable **:用于返回短信列表对应的表结构。
我认为Cemapi中有一个原则(你可以不这么认为),只要出现了IMAPITable接口的对象,就需要采用SizePropTagArray这个宏来声明一个动态结构体,并且调用SetColumns告诉IMAPITable接口对象,列表中的行记录的组织结构。现在我们需要获取行记录中的ENTRYID,然后用这个ENTRYID去Folder中获取对应的短信息对象。
SizedSPropTagArray(1, Columns) = //动态生成结构体对象,只获取Entry ID属性
{
1,
PR_ENTRYID
};
还记得这么声明的意义吗?我们声明了一个动态结构体变量Columns,该结构体中的ULONG值为1(表示数组元素数量),ULONG数组共一个元素,名为PR_ENTRYID。有了这个结构体以后,采用SetColumns方法就可以对表格中行记录结构进行设置了。源代码如下:
IMAPITable *m_pTable = NULL;
m_pFolder->GetContentsTable(0, &m_pTable); //获取该Box下的短信行记录列表
hr = m_pTable->SetColumns((LPSPropTagArray)&Columns, 0); //设置列格式
行记录结构设置完毕以后,与获取MsgStore对象类似,使用QueryRows方法就可以获取该表中所有的行记录了。获取每一行的ENTRYID属性,然后使用IMAPIFolder中的OpenEntry方法(很熟悉吧,没错,就是与获取MsgStore时ImsgStore中的同名方法相同)来获取EntryId对应的短消息了。
获取原始短消息的代码如下:
LPMAPITABLE m_pTable = NULL;
LPSRowSet m_pRows = NULL;
HRESULT hr;
SizedSPropTagArray(1, Columns) = //动态生成结构体对象,只获取Entry ID属性
{
1,
PR_ENTRYID
};
m_pFolder->GetContentsTable(0, &m_pTable); //获取该Box下的内容列表
hr = m_pTable->SetColumns((LPSPropTagArray)&Columns, 0); //设置列记录结构
if(FAILED(hr))
{
//异常处理
}
ULONG ulRowCount=0;
ULONG i=0;
m_pTable->GetRowCount(0,&ulRowCount); //获取列表中行记录总数
while(!FAILED(m_pTable->QueryRows(1, 0, &m_pRows)))
{
if(i==ulRowCount) break; //如果已经遍历完毕
else i++;
IMessage *m_pMsg = NULL;
ULONG ulMesageType;
//通过OpenEntry获取IMessage对象
hr=m_pFolder->OpenEntry( m_pRows->aRow[0].lpProps[0].Value.bin.cb,
(LPENTRYID)m_pRows->aRow[0].lpProps[0].Value.bin.lpb,
NULL,
MAPI_BEST_ACCESS,
&ulMesageType,
(LPUNKNOWN*)&m_pMsg);
if(!FAILED(hr) && NULL!=m_pMsg) //取到了消息
{
//取到了原始消息
}
if(m_pRows)
{
FreemProws(m_pRows); //释放行
m_pRows=NULL;
}
}
if(m_pTable)
{
m_pTable->Release(); //释放表结构
m_pTable=NULL;
}
5.释放IMessage对象.
使用IMessage::Release()方法,可以安全的释放该对象。代码如下:
m_pMsg->Release();
我来回答
回答1个
时间排序
认可量排序
认可0
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币
Markdown 语法
- 加粗**内容**
- 斜体*内容*
- 删除线~~内容~~
- 引用> 引用内容
- 代码`代码`
- 代码块```编程语言↵代码```
- 链接[链接标题](url)
- 无序列表- 内容
- 有序列表1. 内容
- 缩进内容
- 图片![alt](url)
相关问答
-
2012-12-04 11:42:03
-
2012-12-04 11:43:41
-
2012-12-04 11:44:53
-
2010-01-25 13:49:02
-
2008-07-15 23:19:08
-
2012-12-04 11:40:00
-
2012-12-04 11:44:18
-
02012-12-24 14:23:17
-
2012-12-04 11:39:03
-
2012-12-04 11:51:25
-
2018-06-25 15:14:10
-
2020-03-05 18:03:41
-
2020-10-27 14:30:16
-
2013-01-20 00:12:19
-
2013-11-20 18:57:05
-
2013-12-05 22:11:22
-
2019-02-28 13:23:38
-
2023-08-17 15:36:30
-
2015-09-18 10:47:52
无更多相似问答 去提问
点击登录
-- 积分
-- E币
提问
—
收益
—
被采纳
—
我要提问
切换马甲
上一页
下一页
悬赏问答
-
5Hi3516CV610 如何使用SD卡升级固件
-
5cat /dev/logmpp 报错 <3>[ vi] [func]:vi_send_frame_node [line]:99 [info]:vi pic queue is full!
-
50如何获取vpss chn的图像修改后发送至vo
-
5FPGA通过Bt1120传YUV422数据过来,vi接收不到数据——3516dv500
-
50SS928 运行PQtools 拼接 推到设备里有一半画面会异常
-
53536AV100的sample_vdec输出到CVBS显示
-
10海思板子mpp怎么在vi阶段改变视频数据尺寸
-
10HI3559AV100 多摄像头同步模式
-
9海思ss928单路摄像头vio中加入opencv处理并显示
-
10EB-RV1126-BC-191板子运行自己编码的程序
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
提醒
你的问题还没有最佳答案,是否结题,结题后将扣除20%的悬赏金
取消
确认
提醒
你的问题还没有最佳答案,是否结题,结题后将根据回答情况扣除相应悬赏金(1回答=1E币)
取消
确认