《深入BREW开发》——第七章创建新的BREW应用程序第七章创建新的BREW应用程序在第六章中,我们介绍了Applet和模块的相关内容,并且熟悉了BREW开发环境,那么现在是开始创建一个属于我们自己的应用程序的时候了。在BREW中创建应用程序最简单的方式是,通过BREW在VisualStudioC++环境中的应用程序向导。通过向导,可以一步一步的让我们构建成功开发BREW应用程序所需要的组件。接下来我们就详细的介绍一下BREW应用程序的开发方法。7.1写在开发前面的话在进行真正的BREW应用程序开发之前,有一些开发的注意事项需要事先讲明。这样可以让我们避免一些经常性的错误,从而减少开发调试的时间。这些注意事项主要包含如下几个方面:1、从Windows的模拟器移植到BREW设备的问题2、在BREW设备上会出现问题,而在BREW模拟器中不必检测的3、良好的BREW编程习惯通过对这些注意事项的检查,可减少从Windows到BREW设备上的移植任务,同时让程序可以在BREW设备上正确运行。详细内容如下表:注意事项详细描述执行空指针检查关于这一条有如下两个方面:1、在使用ISHELL_CreateInstance()或其他接口函数创建接口实例后,一定要进行接口指针有效性的检查,如果指针异常,则不能够使用这个接口2、检查全部的指针以确认指针有效性,包括传入的、使用BREW方法创建的和分配内存后的。不可用的指针将引起系统的致命错误。避免堆栈溢出由于系统分配给BREW运行环境的堆栈空间是有限的,因此不要在堆栈中分配大数组,也就是说,不要再一个函数的局部变量中声明大数组。如果确实在程序中需要这样的数组,那么,请使用分配内存的方式。不要使用大的循环当一个循环运行的时间足够长时,将引起BREW设备的复位。基于这样的原因,不能在一个BREW事件里进行耗时很长的处理。尽可能的使应用程序成为设备独立的为了使我们的应用程序可以独立于设备的内存大小、键盘数量、颜色深度和屏幕尺寸等因素而独立运行,请使用ISHELL_GetDeviceInfo()方法来获得设备的规格,从而根据不同的规格处理不同的应用程序。使用资源文件使用资源文件存储指定语言的字符串、对话框和图片。这样可以方便的进行不同语言版本的开发,而不影响代码本身。释放内存由于在BREW设备上的可用内存是有限的,因此清理不使用的内存就十分重要了。有如下两种情况:1、必须释放全部创建的实例2、应用程序终止时必须释放全部分配的内存推荐在内存不再使用的时候就释放掉。不要使用全局或静态变量由于全局和局部变量在BREW动态应用程序中无法处理,因此基于这样的BREW架构不支持全局和静态变量,而且全局和静态变量也会引起BREW设备环境下的链接错误。请在应用程序的结构体中声明这些数据。不要在定义的时候初始化一个结构体与上面不能使用全局和静态变量一样,在定义的时候初始化一个结构体也会引起BREW设备环境下的一个链接错误。不要直接使用C语言的浮点运算BREW平台不支持浮点运算。虽然这些运算在模拟器中运行良好,那时因为在Windows环境下,在BREW设备环境下,通常不支持浮点运算。如果确实需要使用的话,请用BREW提供的助手函数进行运算。使用BREW支持的标准库函数为了可以让我们的程序所占的空间最小,请不要使用目标设备的库函数,而是使用BREW提供相应的助手函数。避免类型转换错误由于目标设备的编译器对于类型的检查要严格,因此,请明确声明变量转换的类型,以防止从Windows环境移植到BREW设备环境下产生错误。检查返回值如果我们调用的BREWAPI含有返回值,建议处理这些返回值,这样可以让我们所写的程序更加健壮。7.2创建一个BREW应用程序在这一节里,我们将首先建立一个叫做HelloWorld的应用程序,然后分析这个程序当中的各个要素。也正是从这个例子开始,将正式的带您进入BREW的开发世界。在这本书里,我们使用的环境是VisualStudio.Net开发环境,当然我们也可以使用VisualStudio6.0来创建,并且他们之间看上去没什么太多的不同。7.2.1建立应用程序可以采用如下的步骤建立HelloWorld应用程序:1、我们可以到高通公司的网站上去获取一个名叫HelloWorld的应用程序的ClassID,如果您还没有成为一个授权的BREW应用程序开发者,那么您可以将BREWSDK样例程序HelloWorld中的HelloWorld.bid复制过来。2、使用画图工具或者其他的图片编辑工具为这个应用程序创建图标。图像分为大、中、小三种,我们可以指定bmp、png、bci或jpg图片,图片的大小没有特殊的要求,我们只需要根据您的喜好选定就可以了。不过当程序运行在设备上时,不同的设备由不同的要求,您可以查看该设备的规格说明。3、打开VisualStudio2003。4、打开BREW应用程序向导。通过选择文件-新建-项目菜单,打开创建项目对话框,选择VisualC++项目下的BREWAppWizard项目。在对话框的下部输入应用程序名和应用程序存储路径。点击确定按钮,此时BREW的应用程序向导启动。5、由于我们的应用程序仅需要刷新屏幕,因此保留全部的设置直接点击完成。6、载入MIF文件编辑器,为应用程序创建MIF文件。7、在MIF文件编辑器的Applets选项卡中,新建Applet,并选择我们已经获取的helloworld.bid文件作为次应用程序的ClassID。8、选择应用程序的类型为“Tools”。9、设置我们在第二步创建的三个图标做为应用程序的图标。10、保存文件为helloworld.mfx文件,同时选择“Build-CompileMIFScript”菜单或者按“F5”键,编译二进制文件。由于此命令输出的文件名采用的是DOS短文件名方式,因此请手动修改文件名。11、关闭MIF文件编辑器,返回VisualStudio界面。12、在“项目-helloworld项目属性”对话框的常规选项中,将输出目录置为空,以便于生成的DLL文件可以在根目录中生成。13、在“解决方案资源管理器”中,打开helloworld.c文件。同时输入如下内容:helloworld.c/*====================================================================FILE:helloworld.c====================================================================*//*====================================================================INCLUDESANDVARIABLEDEFINITIONS====================================================================*/#includeAEEModGen.h//Moduleinterfacedefinitions#includeAEEAppGen.h//Appletinterfacedefinitions#includeAEEShell.h//Shellinterfacedefinitions#includehelloworld.bid/*-------------------------------------------------------------------Appletstructure.AllvariablesinherearereferenceviapMe--------------------------------------------------------------------*///createanappletstructurethat'spassedaround.Allvariablesin//herewillbeabletobereferencedasstatic.typedefstruct_helloworld{AEEAppleta;//FirstelementofthisstructuremustbeAEEAppletAEEDeviceInfoDeviceInfo;//alwayshaveaccesstothehardwaredeviceinformation//addyourownvariableshere...}helloworld;/*-------------------------------------------------------------------FunctionPrototypes-------------------------------------------------------------------*/staticbooleanhelloworld_HandleEvent(helloworld*pMe,AEEEventeCode,uint16wParam,uint32dwParam);booleanhelloworld_InitAppData(helloworld*pMe);voidhelloworld_FreeAppData(helloworld*pMe);/*====================================================================FUNCTIONDEFINITIONS====================================================================*//*====================================================================FUNCTION:AEEClsCreateInstanceDESCRIPTIONThisfunctionisinvokedwhiletheappisbeingloaded.AllModulesmustprovidethisfunction.Ensuretoretainthesamenameandparametersforthisfunction.Inhere,themodulemustverifytheClassIDandtheninvoketheAEEApplet_New()functionthathasbeenprovidedinAEEAppGen.c.AfterinvokingAEEApplet_New(),thisfunctioncandoappspecificinitialization.Inthisexample,agenericstructureisprovidedsothatappdevelopersneednotchangeappspecificinitializationsectioneverytimeexceptforacalltoIDisplay_InitAppData().Thisisdoneasfollows:InitAppData()iscalledtoinitializeAppletDatainstance.Itisappdevelopersresponsibilitytofill-inappdatainitializationcodeofInitAppData().AppdeveloperisalsoresponsibletoreleasememoryallocatedfordatacontainedinAppletData--thiscanbedoneinIDisplay_FreeAppData().PROTOTYPE:intAEEClsCreateInstance(AEECLSIDClsId,IShell*pIShell,IModule*po,void**ppObj)PARAMETERS:cl