Symbian 资源文件解析 一、何为资源文件:
在symbian应用程序中,资源文件指的是后缀名为.rss的文件,每个应用程序至少要有一个与之关联的资源文件。资源编译器rcomp编译资源文件后,生成一个.rsc二进制文件和一个相伴的头文件(.rsg)。这样在应用程序框架启动应用程序时,会打开这个二进制文件,借助在.rsg文件中创建的资源标志符,根据需要把各个资源加载到C++代码中。
二、资源文件的作用: 在资源文件中指定用户界面的布局,如常用组件菜单、对话框、列表等在界面上的排列样式,另外还可以在其中指定界面上用户可见的文本信息。当然,这些可见文本并不一定通过字符串在.rss资源文件中定义,我们一般在.loc本地文件中定义,而只需在.rss资源文件中将.loc本地文件引入(include)即可。(刚开始我百思不得其解,真不知道程序终相关的字符串定义在哪里的)
三、资源文件的结构(语法): 资源文件的具体结构由两部分构成,分别称为头部和主体。 1、头部:主要包括五部分,分别是文件名字、include包含语句、签名、文档名缓冲、应用程序信息资源这些些资源文件标准信息。 (1)名字:用NAME语句定义,该语句必须是资源文件中第一个有意义的行(注释和空白语句不在有意义行定义内),即这条语句要位于include包含语句之前,后面没有分号。该语句指定一个由1到4个字符组成的名字,并建议使用大写字符。如果应用程序使用了多个资源文件的话,那么可以通过它进行区分。如:NAME HELL (2)include包含语句:允许使用其他地方定义的符号和结构。常见的有uikon.rh、eikon.rh、avkon.rh等 (3)签名:它的内容实际上被忽略,但必须有这条语句,否则加载资源时便报错。一般将实际内容置为空,如:RESOURCE RSS_SIGNATURE { } ,后面没有分号。 (4)文档名缓冲:指定应用程序默认文档名的TBUF资源。大部分程序不使用文档,但仍然必须包含此资源,否则加载资源失败。不需指定文件的扩展名,因为S60本地文档不使用扩展名。如:RESOURCE TBUF { buffer=”HelloWorld”;} 在这里的文件名将作为参数传递给CAknDocument类的OpenFileL(TBool aDoOpen, const TDesC& aFilename, RFs& aFs)方法。这允许一个应用程序在运行时打开一个默认的文档。如果这里的值为空那么程序默认文档名和应用程序名一致。 (5)应用程序信息资源:这个资源比较重要。EIK_APP_INFO资源为应用程序指定各种标准控件。如状态面板等,通常会创建一个为状态面板指定新内容的资源,然后使用EIK_APP_INFO资源的status_pane字段引用它。如: RESOURCE EIK_APP_INFO { hotkeys = r_HelloWorld_hotkeys; menubar = r_HelloWorld_menubar; cba = R_AVKON_SOFTKEYS_OPTIONS_BACK; } 注意:头部中定义的各种资源都没有资源名。
2、主体 主体部分主要定义了应用程序中将要使用的各种资源。 它的一般定义格式如下: RESOURCE STRUCTNAME resource-name { resource-initializer-list } 在这里STRUCTNAME应替换为具体的资源结构类型,而这些资源结构类型已在文件头部include包含的eikon.rh、uikon.rh、avkon.rh中进行了定义。 资源名resource-name必须小写,通常以r_开头,而在C++文件中使用他们时必须大写,这和资源编译器工作方式有关。例如: //资源名定义 RESOURCE AVKON_VIEW r_viewmychannelhot { hotkeys=r_xv_hotkeys; menubar=r_menubar_viewmychannelhot; cba=R_AVKON_SOFTKEYS_SELECTION_LIST; } //资源调用 BaseConstructL(R_VIEWMYCHANNELHOT); 下面具体研究resource-initializer-list(初始化资源字段),根据要资源字段的不同类型,初始化字段有三种不同方式:简单初始化器、数组初始化器、结构初始化器。如下: RESOURCE STRUCT r_my_example_struct { simple=EeikCtLabel; //简单初始化器,分配单个值或字符串 array={1,2,3}; //数组初始化器,大括号,元素用逗号隔开 structmember=OTHERSTRUCT //结构初始化器,编译器不进行类型检查,要小心 { simple1=”hello”; simple2=”goodbye”; } } 由以上示例可知: 简单初始化器:为字段分配单个值或字符串; 数组初始化器:为数组字段分配单个或多个值,格式用大括号括起,其中元素用逗号隔开; 结构初始化器:为结构字段分配单个或多个值。首先初始化时需要提供结构名,而后指定结构每个字段;其次资源编译器不进行类型检查,所哦一设定值时必须与结构字段相应类型一致,否则编译能通过但是运行会出错。
由于采用不同的控件时,其采用的资源字段各不相同,所以先分析三类具体的资源定义,具体控件的资源定义,放在具体控件中阐述。 (1)字符串资源: 可以使用TBUF资源将字符串包含在资源文件中。通常,会在一个.loc文件中或是在指定语言的.lxx文件中定义字符串文字,而不是在.rss文件中定义它们,只需在.rss文件中将.loc文件包含进来即可。 .lxx文件中的xx应该替换为e32std.h中的Tlanguage枚举定义的两位数字区域设置码,之后按照.mmp项目文件中设置的当前生成区域设置把.lxx文件包含到.loc文件中。看一个定义了.lxx文件的.loc文件实例: #ifdef LANGUAGE_01 #i nclude “MyApp.101” #endif #ifdef LANGUAGE_02 #i nclude “MyApp.l02” #endif 最后,.101和.102文件以各自的语言定义字符串,比如: #define STR_HELL0 “Hello World” 为了确保编译资源时将使用正确的字符串,应该在.mmp文件中包含一行或多行LANG语句,导致生成两个二进制资源文件:.r01和.r02。 LANG 01 LANG 02 (2)标点:介绍如何使用标点符号 a、所有赋值语句之后都应该有分号 b、列表中的元素以逗号分隔 c、资源定义后以及列表中最后一个元素之后不应有分号 举例: RESOURCE AVKON_VIEW r_myapp_view { menubar=r_myapp_menubar;//赋值语句后有分号 cba=r_myapp_cba;//赋值,需要分号 } //资源定义结尾,无需分号 … RESOURCE TAB_GROUP r_myapp_tabgroup { tab_width=EaknTabWidthWithTwoTabs; active = 0; tabs = { TAB //列表中的第一个TAB STRUCT { id = EnavigationPaneTab1; txt = TAB1_TEXT; }, //列表元素之间用逗号分隔 TAB { id = EnavigationPaneTab2; txt = TAB2_TEXT; } //列表结尾无需分号 }; //将列表赋值给tabs,需要分号。 } |