Hello World 上面一节我们建立好了开发环境,现在是时候实战一把了,在进行实质性的项目开发之前,我们先来了解下P1300上写程序的一般性做法。从“Hello World”开始吧,有句笑话讲:“会编程就是会Hello World,编程高手就是会写很多个Hello World”,虽然是句笑话,但是细想也是有道理的,麻雀虽小五脏俱全嘛,掌握了框架,剩下的就无非是些编程技巧的问题了。这和建房子一个道理,地基打的深不深,框架建的是否合理,决定房屋总体质量好不好,其他就是装修的功夫了,当然还有水电线路的铺设,这涉及到习惯和技巧了,设计不好会漏水漏电,哈哈。扯远了,下面开始Hello World。 下面为描述上的方便,我们将Hello World称为一个模块。首先建立新的模块目录,之后把模块相关文件都放到这个目录下统一进行管理,新的模块一般放到plutommiMMI下面,这里我们新建一个目录“HelloWorld”,然后在模块目录“HelloWorld”下再建三个子目录:“Inc”、“Src”和“Res”,分别用来存放模块的头文件、源文件和资源文件,目录结构如下图所示:
 接着我们在Inc下创建几个头文件:HelloWorldGprot.h,HelloWorldProt.h, HelloWorldTypes.h, HelloWorldDefs.h, 再在Src下创建一个源文件:HelloWorld.c,关于文件名和函数名等的命名标准每个公司及个人各有不同,统一就好,否则在进行大的项目开发时彼此协同会遇到问题,有时候弄不好光这些问题就能折腾你半天甚至数日或数月,呵呵。 上面几个文件的作用我大致讲下: HelloWorldGprot.h 模块对外接口,供模块外部调用的函数原型在此申明,模块内部接口就不要放这里了 HelloWorldProt.h 模块内部接口,供模块内部调用的函数原型在此申明 HelloWorldTypes.h 本模块用到的一些常量、自定义数据类型、结构的定义 HelloWorldDefs.h 本模块用到的资源ID定义 HelloWorld.c 模块功能函数的实现部分 头文件HelloWorldGprot.h的内容大致如下: /*************************************************************************/ #ifndef __HELLOWORLD_GPROT_H__ #define __HELLOWORLD_GPROT_H__ #include "PixtelDataTypes.h" #include "HelloWorldTypes.h" extern void mmi_HelloWorld_entry(void);/* 模块入口,理解成dos程序的main好了 */ #endif /* __HELLOWORLD_GPROT_H__ */ /*************************************************************************/ 头文件HelloWorldProt.h的内容的大致如下: /*************************************************************************/ #ifndef __HELLOWORLD_PROT_H__ #define __HELLOWORLD_PROT_H__ #include "HelloWorldGprot.h" extern void mmi_HelloWorld_entry(void); /* 本模块主界面入口例程 */ extern void mmi_HelloWorld_exit(void); /* 本模块主界面退出例程 */ #endif /* __HELLOWORLD_PROT_H__ */ /*************************************************************************/ 其他几个文件的内容因模块功能而异,这里先略过,后面再讲。 紧接着,我们要修改的相关系统文件,使这个模块成为整个项目的一部分,需要修改的系统文件如下: makeplutommiplutommi.inc 所有mmi部分的头文件所在目录的相对路径列表 makeplutommiplutommi.pth 所有mmi部分的源文件所在目录的相对路径列表 makeplutommiplutommi.lis 所有mmi部分的源文件(相对路径)列表 在上述3个文件里面分别加上我们模块的对应内容,就现在讲的HelloWorld而言,所加内容如下: makeplutommiplutommi.inc文件追加一行“plutommimmiHelloWorldInc” makeplutommiplutommi.pth文件追加一行“plutommimmiHelloWorldSrc” makeplutommiplutommi.lis文件追加一行“plutommimmiHelloWorldSrcHelloWorld.c” 再接着,我们需要增加一个开关,以决定这个模块是否成为最终发布版本的一部分,这实际上是一个编译开关,需要修改系统文件及相关的模块源文件,需要修改的系统文件包括: plutommiCustomerCustResourcePLUTO_MMIMMI_featuresPLUTO.h,这里我们用 名字为“__MMI_HELLOWORLD_ENABLED__”这个开关好了,在这个文件里面追加一行: #define __MMI_HELLOWORLD_ENABLED__,同时在相关源文件里面用: #ifdef __MMI_HELLOWORLD_ENABLED__ #endif 来框住相关代码行就OK了,当不打算将这个模块发布的时候,注释掉“#define __MMI_HELLOWORLD_ENABLED__”这一句重新make一次就好了。 下面讲具体实现的部分,为了简化描述,我们暂时先将我们的模块入口挂接到主菜单入口处(后面讲到资源的部分可将入口移到某个新建的子菜单下),修改下文件“plutommimmimainmenumainmenusrcMainMenu.c”中的goto_main_menu函数,如下所示红色字体部分: void goto_main_menu(void) { #ifdef __MMI_HELLOWORLD_ENABLED__ mmi_HelloWorld_entry(); return; #else … // 此处为之前goto_main_menu的代码 #endif } 同时我们需要在文件MainMenu.c中包含头文件HelloWorldGprot.h,所以再在这个文件的头文件包含代码块(通常是文件的顶部区域)追加这一句:#include "HelloWorldGprot.h"。 下面是HelloWorld.c的内容: /*************************************************************************/ #include "stdC.h" #include "MMI_Features.h" /* 编译开关会出现在这个由make update生成的文件里面 */ #include "L4Dr.h" #include "L4Dr1.h" #include "AllAppGprot.h" #include "FrameworkStruct.h" #include "GlobalConstants.h" #include "EventsGprot.h" #include "mmiappfnptrs.h" #include "HistoryGprot.h" #include "HelloWorldProt.h" #include "HelloWorldTypes.h" #include "HelloWorldDefs.h" #include "MainMenuDef.h" #include "wgui_categories.h" #include "Unicodexdcl.h" /* 模块入口 */ void mmi_HelloWorld_entry(void) { #ifdef __MMI_HELLOWORLD_ENABLED__ /* 强制退出当前屏幕,之后进入到我们的模块了 */ /* 上电缺省是idle屏幕,现进入MAIN_MENU_SCREENID屏 */ /* 注意看第二个参数,这个是当我们模块被强制退出时执行的一些操作 */ EntryNewScreen(MAIN_MENU_SCREENID, mmi_HelloWorld_exit, NULL, NULL); /* 关掉屏幕顶部的状态条,我们要用整个屏幕 */ entry_full_screen(); /* 擦除当前背景 */ clear_screen(); /* 移动文本输出光标 */ gui_move_text_cursor(50, 100); /* 设置字体颜色 */ gui_set_text_color(UI_COLOR_RED); /* 输出文本到显示缓冲, 注意是Unicode编码 */ gui_print_text(L"Hello, World"); /* 刷新屏幕显示,MMI用的是双缓冲绘图方式,而且需要显式刷新 */ gui_BLT_double_buffer(0, 0, UI_device_width - 1, UI_device_height - 1); /* 注册一个按键处理,右软键弹起时返回到之前被我们强制退出的模块 */ SetKeyHandler(GoBackHistory, KEY_RSK, KEY_EVENT_UP); #endif } /* 模块出口 * 当我们的模块被其他模块强制退出时会执行这个函数, * 这个函数的常见写法,包括: * 1、模块已申请资源的释放(如果需要的话),这一步可选 * 2、手动把自己压栈到窗口(实际是整个屏)堆栈里面, * 便于强制我们退出的模块执行完后重新把我们叫出来 * 不像Window的窗口管理是自动压栈的,Pluto MMI需要手动压栈 * 3、其他一些清理动作 */ void mmi_HelloWorld_exit(void) { #ifdef __MMI_HELLOWORLD_ENABLED__ history currHistory; S16 nHistory = 0; currHistory.scrnID = MAIN_MENU_SCREENID; currHistory.entryFuncPtr = mmi_HelloWorld_entry; pfnUnicodeStrcpy( (S8*)currHistory.inputBuffer, (S8*)&nHistory); AddHistory(currHistory); #endif } /*************************************************************************/ 编码的部分基本上就是这些了,然后我们开始make,这次要用“make update”,基于上述对相关系统文件的改动,make update会自动将刚才的模块加入到整个项目中去,同时也会更新仿真器VC工程文件,如下图所示,HelloWorld模块的相关文件已经被自动加入到MMI库里面了:
 后续的make,如果是不涉及到系统相关文件的修改,用“make remake”就可以了,以节省编译时间,因为make一次太耗时间了。 注意:对于仿真程序的编译,“make update”似乎缺少一些处理,导致可能还需要手工在文件“plutommimmiGlobalSimulatorPathDef”中追加一行,以便模块的头文件能被顺利找到,如下所示: /I ".HelloWorldInc" 好,现在编译仿真程序开始看下效果,编译 (make update会清除掉仿真程序之前编译的中间文件,这样仿真程序会整个重新编译) 完后运行仿真器程序,如下图所示,点选File->Network Simulator启动仿真,启动后手机模拟器进入Idle画面,点选手机模拟画面上的“菜单”,就进入到我们的Hello World了,而不是之前的主菜单,然后点右按钮,画面回到Idle画面。
 至此,Hello World基本完成,这是一个相对完整的模块框架,在此基础之上我们可以逐步开始进入真正有意义的项目开发了。 未完待续…… |