CEMAPI实战攻略(一)
By 吴春雷
QQ:819543772
EMAIL:[email protected]
一.准备工作
1. 开发环境和设备平台
a) 下载和安装
微软已经发布了Windows Mobile 6.0 SDK和中文版的仿真器已,WM6.0的SDK和仿真器分成了标准版和专业版两个版本,由于两个版本都可以支持cemapi.lib,因此我们可以选用其中任意一个版本作为我们的开发平台。本文选择了WM6.0 SDK Professional和WM6.0 中文版仿真器,下载地址如下:
Windows Mobile 6.0 SDK professional:
http://download.microsoft.com/download/f/2/3/f232f773-7edc-4300-be07-d3b76a5b3a91/Windows%20Mobile%206%20Professional%20SDK%20Refresh.msi
Windows Mobile 6.0 中文版仿真器:
http://download.microsoft.com/download/0/1/2/012bfbba-9fe5-4e68-86c9-d434446d97dd/0804/Windows%20Mobile%206%20Professional%20Images%20(CHS).msi
另外,本文最后一部分所要用到的MapiRule程序再WM6.0 SDK的sample中没有给出,因此为了更好的讨论本文的最后一部分,还需要下载MapiRule这个源程序。我建议大家直接安装Windows Mobile 5.0 SDK,在WM5.0SDK的目录下我们可以找到该源程序。至于为什么不选用WM5.0 SDK作为我们的开发环境,下一部分您就会了解到。WM 5.0 SDK和仿真器的下载地址是:
http://download.microsoft.com/download/6/0/8/608530c5-7e9a-4032-bf18-92d90b5f4ab4/WM Developer Resource Kit.msi
成功安装SDK以后,我们可以在建立一个智能设备应用程序平台选择的“已安装的SDK”列表中看到上述两个平台的名称。见下图:
图1.1
另外,本文所讨论的内容以及所有源代码均在Windows XP,VS2005,WM5.0/6.0和夏新的N810(WM5.0系统)平台上测试和实现。
b) 如何使用Cellular emulator测试我的短信应用程序
与开发一般的应用程序不同,使用cemapi库开发短信应用程序会遇到的第一个问题,也是非常关键的问题就是如何测试程序。再真机上开发我们可以通过飞信等免费的短信发送工具对应用程序进行测试,但通常我们没有在真机上开发应用程序的条件和环境,那么我们该如何对短信应用程序进行测试呢?在WM6.0 SDK推出以前,我们都是采用在模拟器中向14250010001这个号码发送短信的方式来测试短信应用。这个号码是模拟器默认的本机号码,向这个号码发送短信,模拟器将会收到所发送的信息。这个号码是您首先应该记住的。但是仅仅使用这些去测试我们的应用程序还是远远不够的,因为您在模拟器中所接收到的短信,发送者和接受者的属性将永远是14250010001这个号码,显然,我们需要更强大的测试环境。
可喜(或者是可悲)的是,微软终于也意识到了这个问题,为了更好的帮助PPC手机软件的开发者工作,WM 6.0 SDK中提供了一个名为Cellular Emulator的小工具。通过这个小软件,我们可以用不同的号码想模拟器发送短信或拨打电话,模拟器可以再相对更大的范围内进行测试。不幸的是,这个小工具只支持WM 6.0 仿真器,这是我选择了WM 6.0 SDK作为本文的开发平台的主要原因。
下面以Step by Step的方式介绍一下Cellular Emulator的安装与使用,以及再WM仿真器上的设置方法。别担心,这非常简单。
首先,如果您已经成功安装了WM6.0 SDK ,那么您实际上已经完成了Cellular Emulator的配置,您可以选择“开始菜单”——“Windows Mobile 6.0 SDK”——“tools”——“Cellular Emulator”来启动该程序。如果您没有安装WM6.0 SDK,又想使用Cellular Emulator(我不知道再不安装WM 6.0SDK的情况下使用安装这个软件有什么意义),您可以在网络上找到相关资料。
其次,我们需要对WM仿真器端做一个简单的设置。请按照上面的步骤运行Cellular Emulator,注意界面左下角,记住这个COM端口号码(见图1.2)。然后启动WM仿真器(这个大家都应该会的),选择“文件”——“配置…”打开“仿真程序属性”对话框,选择“外围设备”tab页,可以看到“串行端口0”标题,见图1.3和图1.4
图1.2
图1.3
图1.4
还记得刚才在Cellular Emulator上记住的哪个端口吗?(图1.2),将这个端口填入“串行端口0”的位置(如果下来菜单中没有,你可以手动输入),然后重新启动仿真器即可。
Cellular Emulator的设置已经全部完成了。很容易,不是吗?接下来我们利用它发一条短信给仿真器。启动Cellular Emulator,选择“SMS”tab标签,在“send to device”对话框中填入你所要发送的短信内容,并在下面的“phone number”位置填入任意号码,单击“send”,然后耐心的等上几秒,WM6.0仿真器就会收到这条短信。值得注意的是,Cellular Emulator目前还不支持中文短信的发送,因此如果您想测试中文短信,那么还是要采用向本机号码14250010001发送短信的方式来进行测试。Cellular Emulator还有很多其它有趣的功能,由于与本文讨论的内容无关,如果有兴趣,大家自己来挖掘吧。
注:如果仿真器没有接收到短信,请重启一下计算机
c) 如果使用的是WM5.0以前版本,我该如何测试我的程序?
前面已经提到过了,每个WM仿真器都会绑定一个号码作为本机号码,您应该记住这个号码:14250010001,您可以向这个号码发送短信,这样WM模拟器可以接收到这条短信。不过,短信的收件人和发件人属性将永远是14250010001。
2. 如何导入Cemapi库、
Cemapi提供了dll和lib两种形式共开发者调用,本文选用最传统的lib调用方式来使用该库(这不意味着你就可以不用dll文件,lib中存放的只是符号的声明,真正的实现再dll中)。与所有lib静态库一样,cemapi也包括cemapi.h和cemapi.lib两部分,我们可以像导入其它库的方式导入该lib库。两种方式如下:
第一种方式:再菜单中单击“项目”——“属性”进入“项目属性页”,在“项目属性页”左侧的树形列表中选择“配置属性”——“连接器”——“输入”,在右侧“附加依赖项”的位置输入cemapi.lib,见图1.5
图1.5
第二种方法:在源程序中加入如下代码,同样可以导入静态库
#pragma comment(lib,”cemapi.lib”)
采用上述两种方式导入lib库以后,需要再源程序中包含cemapi.h头文件,这样我们就可以使用cemapi中对象了。
3. 初始化和释放MAPI
像使用CSocket连接开发网络应用程序时,需要进行初始化一样,在使用cemapi前也需要对先对组件进行初始化。由于cemapi用到了COM组件库,因此首先需要调用CoInitializeEx()对COM组件库进行初始化,然后再调用MAPIInitialize()对CEMAPI进行初始化,这样做的目的是告诉系统,从现在开始我要使用CEMAPI了。当不再需要使用CEMAPI的时候,我们需要使用MAPIUninitialize()和CoUninitailize()函数释放对CEMAPI和COM的引用。CoInitializeEx函数不再本文的讨论范围之内,我们只给出它的调用方式,至于为什么要选择这些参数,以及这些参数的作用,大家可以再网络上搜集一下相关资料,调用代码如下:
HRESULT hr;
hr=CoInitializeEx(NULL,COINIT_MULTITHREADED); //初始化COM
if(FAILED(hr))
{
//异常处理
}
MPAIInitialize(LPVOID lpMapiInit) 以函数指针的形式被被定义在mapix.h文件中,其定义如下:
typedef HRESULT (STDAPICALLTYPE MAPIINITIALIZE)(
LPVOID lpMapiInit
);
MAPIINITIALIZE MAPIInitialize;
该函数返回一个HRESULT类型的对象,我们可以通过它来判断函数是否调用成功。
MAPIInitialize函数有一个LPVOID参数,这个参数再CEMAPI中是不需要的。由于CEMAPI来自与MAPI,而MAPI原本用于再Windows平台下对Exchange,Outlook等邮件系统进行操作的而封装的库,当再桌面系统上的不同平台上运行时,可以通过传递给MAPIInitialize函数一个MAPIINIT_0的结构体来确定使用的版本和工作平台(比如NT系统)。CEMAPI是MAPI在移动平台上的版本,因此保留了函数原型,这个参数在Mobile上并没有被用到,直接设置为NULL即可。
当使用完毕以后,需要采用如下方式释放对CEMAPI的调用以及对COM库的引用。
MAPIUninitialize();
CoUninitialize();
4. 本小节的源程序
//初始化CEMAPI
void InitMAPI()
{
HRESULT hr=0;
hr=CoInitializeEx(NULL,COINIT_MULTITHREADED); //初始化COM
if(FAILED(hr))
{
//异常处理
}
hr=MAPIInitialize(NULL); //初始化MAPI
if(FAILED(hr))
{
//异常处理
}
return;
}
//释放CEMAPI
void UnInit()
{
HRESULT hr;
hr=MAPIUninitialize();
if(FAILED(hr))
{
//异常处理
}
CoUninitialize();
return;
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/depraved_survival/archive/2009/03/08/3969021.aspx