MapiRule使用心得
前言
关键字:Windows Mobile MapiRule, MapiRule 使用
关于MapiRule这里就不介绍了,主要介绍一下使用的心得和需要注意的问题。
文章
1. CMAPI实战攻略(系列文章) 重点是系列文章第六篇
3. Windows Mobile 6 SDK 中的 Cellular Emulator
环境
1. 真机系统:Windows Mobile 6.1
2. 开发工具:Microsoft Visual Studio 2005
3. SDK版本:Windows Mobile 6 SDK
正文
一、准备
示例位置:Windows Mobile 6 SDK\Samples\Common\CPP\Win32\MapiRule
拷贝一份出来,用Visual Studio 2005打开项目即可。
二、工作原理[摘自文章1]
MapiRule实际上是利用COM技术对tmail.exe功能进行扩展。像所有com程序一样,系统提供了一个接 口(协议)来让外部程序实现,外部程序通过实现该接口来为tmail.exe增加新的功能。CMapiClient是一组接口,当短信到达本地设备的时候,系统会调用一系列的函数获取并加载COM组件,然后调用ProcessMessage方法来处理到达的短消息,这个过程由系统实现,除了 ProcessMessage方法以外不需要我们来写任何程序。
注意其实MapiRule拦截下来的时候,短信已经到达了短信(邮件)仓库,但没有到具体的信箱(如收件箱、发件箱等),所以这里处理完之后,会调用DeleteMessage来删除短信。
三、 使用和代码说明
3.1 使用说明
MapiRule的工作机制是基于COM技术的,这里只需要注册该Com组件即可,有三种方法,参加文章一,这里使用安装Cab包的方式注册。编译MapiRule工程,然后编译SetupMapiRule,拷贝在SetupMapiRule\Debug下的SetupMapiRule.CAB和SetupMapiRule.inf两个文件到Windows Mobile模拟器或者真机上安装即可。注意需要重起下系统,到这里为止还没有修改过一行代码,用真机或者Cellular Emulator测试,发送一条短信内容为"zzz"即可,即可看到效果!
3.2 代码说明
短信内容: pspvSubject->Value.lpszW
短信号码: pspvEmail->Value.lpszW
短信时间: 依次对应上面两项加入以下代码即可获取
//...
SizedSPropTagArray(1, sptaTime) = { 1, PR_MESSAGE_DELIVERY_TIME};
//...
SPropValue *pspvTime = NULL;
//...
hr = pMsg->GetProps((SPropTagArray *) &sptaTime, MAPI_UNICODE, &cValues, &pspvTime);
if (FAILED(hr))
{
goto Exit;
}
//格式化时间
FILETIME ft;
SYSTEMTIME stTime;
FileTimeToLocalFileTime(&pspvTime ->Value.ft,&ft);
FileTimeToSystemTime(&ft,&stTime);
进程通讯:
这里采用窗口消息 WM_COPYDATA方法进行数据传递,并且这里将数据打包成了结构体。
结构体:
{
TCHAR chMobile[20]; //电话号码
TCHAR chSubject[140]; //短信内容
SYSTEMTIME SendTime; //发送时间
}Sms;
发送方(MapiRule):
memset(&sms,0,sizeof(Sms));
HWND pWnd = FindWindow(NULL,L"你主窗体的标题");
if(pWnd == NULL){
goto Exit;
}
wcscpy(sms.chSubject,pspvSubject->Value.lpszW);
wcscpy(sms.chMobile,pspvEmail->Value.lpszW);
sms.SendTime = stTime;
COPYDATASTRUCT cpd; //给COPYDATASTRUCT结构赋值
cpd.dwData = 0;
cpd.cbData = sizeof(sms);
cpd.lpData = (void*)&sms;
::SendMessage(pWnd,WM_COPYDATA,NULL,(LPARAM)&cpd);
接收方:主窗体消息队列
ON_WM_COPYDATA()
END_MESSAGE_MAP()
BOOL CYouWindow::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
Sms* store = (Sms*)pCopyDataStruct->lpData;
}
四、注意
1. 如果以安装的方式部署的MapiRule,安装完之后需要重启一下,不然可能会截获不到的情况。
2. 编译出错,说是签名工具问题,关掉MapiRule和SetupMapiRule项目中的证书即可:项目 - Authenticode签名 - 否;或者参照文章1里面的办法。
3. 关于如何拷贝安装包到模拟器上,可以通过共享文件夹或者随其他工程一起当做文件来发布到模拟器上。
结束语
RIL拦截短信在真机上测试失败, 后来发现很多人都是用MapiRule来实现的,现成的例子,顺便发现SDK下好多例子,有空打算每一个都跑一下看看。如果想进一步操作短信相关的东西,强烈推荐看完文章1的系列文章。