使用Carbide.vs与VS.NET2003构建Symbian开发平台-S60 平台(三)
Posted on 2009-06-11 18:20 peterzb 阅读(495) 评论(0) 编辑 收藏 举报4.在HelloWorld里面显示图像
接下来我们将让HelloWorld项目显示一个简单的图像。第一步,制作 一张 bmp 的图像文件,并保存到你的项目的路径下的 data 目录下,在教程里的项目是保存在C:\Symbian\Dev\HelloWorld\中的,所以我们制作 了一张 名为 Picture.bmp 的图像文件并保存在 C:\Symbian\Dev\HelloWorld\data 目录下,或者你可以直接通过打开VS.NET 2003的项目资源管理器,在data目录上右击选择 添加->添加现有项->选择Picutre.bmp以添加到项目中去。
对于位图文件,Symbian 建议把所有的位图都打包进一种扩展名为 *.mbm 的文件里面,*.mbm 其实是一种位图集文件,里面可以包含很多的位图,类似于windows平台的资源文件,将程序里要用到的位图打包进 *.mbm 文件里后,我们在程序里就可以很方便 地使用这些位图文件。在还没有第三方辅助工具的应用前,要打包位图生成 *.mbm 需要自己编写脚本去实现,现在有了Carbide.vs我们可以很方便地将我们的位图打包进 *.mbm 文件里面,只要我们在 项目名.mmp (在教程里是HelloWorld.mmp) 文件上点击右键选择。Bitmap Collection Tool ,打开后选择 Current Directory 指定你的data目录,就会在左下角的Available bitmaps 列表中显示可用的位图文件,然后再把你所需要的位图文件移到右边的 Selected bitmaps 中,Display size:在这里我们设置成了 176 x 208 因为我们是要生成S60 2.x的应用程序,所以我们选择 176 x 208的分辨率
编辑完成后编译生成一下项目,这样就会在SYMBIAN 的模拟器目录中生成 一个所谓的 HelloWorld.mbm 与 HelloWorld.mbg 文件,在SYMBIAN的SDK目录下搜索找到 HelloWorld.mbg并用记事本打开,你可以看到以下的类似内容
enum TMbmHelloworld
{
EMbmHelloworldPicture
};
这个枚举类型TMbmHelloworld就是HelloWorld项目的位图定义了,刚才我们已经添加了一个名为Picutre.bmp的位图文件,EMbmHelloworldPicture就是对应了我们的那个Picutre.bmp位图文件,接下来我们的任务就是让HelloWorld显示这个位图。
在这之前我们提过HelloWorld.mbm文件,其实这个才我们程序里真正要载入的位图资源文件。打开HelloWorldContainer.h,在CEikLabel类的定义前面输入以下代码
#include "HelloWorld.mbg"
_LIT(KMbmFileName,"HelloWorld.mbm");
刚看到 _LIT 很多人会问起这是一个什么函数啊,其实这个不是函数,这个是一个预定义宏,在这里我们通过_LIT宏将"HelloWorld.mbm"这个字串赋值给KMbmFileName常量,其实在Symbian 里面没有类似windows平台的字符串类型(string),取得代之的是被称做 描述符(descriptor)的对象 。关于描述符的更多帮助请查看相关的资料。
Symbian os 手机操作系统的文件系统与windows的文件系统是类似的,所以只给出一个"HelloWorld.mbm"文件不足以让程序找到这个文件的具体位置并装载进程序里,此时我们需要取得这个文件在操作系统里的绝对路径,请打开 HelloWorldContainer.cpp 文件,在CHelloWorldContainer::ConstructL 函数里添加以下的代码,
TFileName fullName(KMbmFileName);
CompleteWithAppPath(fullName);//自动为文件名添加文件路径
在这里我们创建了一个标准的可修改标识符fullName,包含了我们的mbm文件名,接下去的第二行代码则把应用程序的路径添加到这个fullName中,使fullName成为一个绝对的文件路径。估计到这里,你应该可以猜出ConstructL函数是什么意思了吧?呵呵,好了,让我们编译一下程序,跟踪一下fullName是一个什么路径吧,按上F5,等待............不是吧,出错了,VS.NET报出了
error C3861: “CompleteWithAppPath”: 即使使用参数相关的查找,也未找到标识符 的错误,有过一定编程基础的人会想到肯定是哪个文件或库没有给引进来,猜对了,我们需要把一个 aknutils.h 的头文件包含进我们的源代码中,请打开 HelloWorldContainer.h 并加入 #include "aknutils.h"。加完后再试试,是不是已经不会报错了?
如果你想知道fullName到底会是一个什么样的值,你可以在 CompleteWithAppPath(fullName);的下一行代码处设置一个断点,按F5编译生成并运行模拟器,打开你的程序,运行到了断点处时,程序会停下来,光标定位在了IDE窗口,通过IDE的自动窗口我们可以看到fullName此时的值 。
此时我们发现fullName的值为 Z:\System\Apps\helloworld\HelloWorld.mbm,(如果你没有发现以上的窗口,请依次打开VS.NET的菜单 调试->窗口->自动窗口)。在这里 Z 代表了手机模拟器的驱动器,当你安装到了目标手机上后,这个驱动器就会变成C,或者是E了。
好了,接下来我们来让程序显示出我们添加的位图。首先我们在HelloWorldContainer.h 头文件中添加以下代码
CFbsBitmap* iImage;
接着定位到HelloWorldContainer.cpp 的ConstructL函数中,在我们之前编写的代码下面输入
iImage = new (ELeave) CFbsBitmap();
User::LeaveIfError(iImage->Load(fullName,EMbmHelloworldPicture));
再定位到 HelloWorldContainer.cpp 的Draw()函数 并在最后面输入
gc.BitBlt(TPoint(0,0),iImage);
这样就通过了图形上下文(graphics context,gc)将你的位图复制到了屏幕的左上角。
编译一下,OH,MY GOD ,又出错。具体错误信息为
HelloWorld error LNK2019: 无法解析的外部符号 "public: __thiscall CFbsBitmap::CFbsBitmap(void)" (??0CFbsBitmap@@QAE@XZ) ,该符号在函数 "public: void __thiscall CHelloWorldContainer::ConstructL(class TRect const &)" (?ConstructL@CHelloWorldContainer@@QAEXABVTRect@@@Z) 中被引用
HelloWorld error LNK2019: 无法解析的外部符号 "public: int __thiscall CFbsBitmap::Load(class TDesC16 const &,long,int)" (?Load@CFbsBitmap@@QAEHABVTDesC16@@JH@Z) ,该符号在函数 "public: void __thiscall CHelloWorldContainer::ConstructL(class TRect const &)" (?ConstructL@CHelloWorldContainer@@QAEXABVTRect@@@Z) 中被引用
还是同样的原理, 我们要引入一个库文件才能解决这个问题,请在项目资源管理器中右击项目->属性->配置属性->链接器->命令行 ,在右边的 附加选项 中输入 fbscli.lib
再次编译,OK了,好现在我们运行这个程序,哈哈,图像在我们的程序里显示出来啦。好高兴。
作者:peterzb(个人开发历程知识库 -
博客园)
出处:http://peterzb.cnblogs.com/
文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。