×
Namespaces

Variants
Actions

应用程序资源

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

兼容于
平台:
Symbian

文章
huwell 在 28 Jun 2007 创建
最后由 hamishwillee 在 08 May 2013 编辑

Contents

概述

大部分的信息定义了一个symbainOS应用程序的外观、行为和功能,它们都存储在一个外部的资源文件当中。它不象其他的程序环境,在一个单独的可执行的的文件中包含了代码和所有的信息。资源文件可以使得程序仅在需要时才载入资源,从而能减少RAM的需要量,他们可以被压缩,也可以在不用重新编译主程序的情况下进行修改,如可以本地化资源操作。

资源文件是使用symbian os特有的资源语言来书写的一个文本文件。这些源文件最终被编译为一个二进制文件格式,可以被程序载入并读取。源文件可以在命令行使用资源编译工具(epocrc)来进行编译,或者做为标准工程的一部分而在命令行或IDE中进行编译。


为什么要用资源文件

资源文件可以使用在如下情况: 1、应用程序用户界面定义:c++应用程序编程框架需要一个应用程序的布局和行为等特性,如一个定义在资源文件中的菜单。

2、应用程序信息文件(aif):这是一个特殊类型的资源文件,它定义了程序在系统上下文中的属性,这些属性包括应用程序出现在shell中的图,;该程序在系统shell中是否可见,是否可以在系统上下文中生成该程序的新文档,以及该程序是否是内嵌的,还有就是该程序是否和特定的MIME数据类型相联系。

3、字符串和其他常量数据:如对话框文字和错误信息,resource tool chain提供对这些资源的本地化支持。


文件类型参考

资源编译过程使用如下一些文件类型: rss 资源源文件。 rls 定义局部化字符串,这些是由资源源文件中所包含。 h 头文件,在c++文件中包含。 rh 资源头文件,是在资源源文件中所包含的。 hrh 普通的c++或资源头文件,可以被任一种源文件所包含。 rsg 是在资源编译后生成的资源头文件 rsc 由资源编译器编译好的资源文件 aif 应用程序信息文件,是按application architecture所定义的,由Aiftool生成


如何创建一个资源文件

资源的编译是由资源编译器(epocrc)工具所处理的,它有三个步骤:

  • 预处理
  • 本地字符串合并
  • 编译成二进制格式

下面就挨个狠狠的解释一下:)

预处理

资源文件可以使用常见的预编译指示,特别的是,#include是用来包含头文件的;#define是用来定义宏的,如数字常量等;#if和相关的指令可以用来处理有条件的编译;预编译中有关包含文件路径和宏定义的参数可以由预编译工具epocrc传递进去。

编译生成的预处理文件后缀为.rpp。


本地字符串合并

字符串应该本地化处理,但不应该在资源文件中定义,可以在一个单独的文件.rls中存放。epocrc在处理rpp文件时会并进本地化字符串。

我们可以指定一个flag,从而使得epocrc将.rpp文件拷贝到epoc32\localisation\目录中,从那.rpp文件可以输入到一个localisation kit中去。


编译成二进制格式

最终的一步是将中间文件.rpp转化为最后的编译格式。这是用rcompl工具编译的。资源编译器也最终生成了一个头文件,里面包含的是每个资源的symbolic identifier。

输出文件的名字是在epocrc中做为参数指定的,注意:

  • 资源文件被工程编译工具abld编译为.rsc后缀的文件。
  • 一般来说头文件编译后,后缀为.rsg。

资源头文件中的识别码提供了资源文件内容的索引信息,你的程序中只要识别这些即可引用资源文件相关内容了。

RESOURCE TBUF r_eik_bafl_error_offset (buf="Wrong format resource file";)
 
编译后生成的头文件将为:
#define R_EIK_BAFL_ERROR_OFFSET 0xf3b045


这里的数字(0xf3b045)就是资源ID,它对资源索引进行编码,这样可以做为参数传递到c++函数RResourcefile::AllocReadLC()。

怎样将资源本地化

概述

开发者可以本地化C++程序,只要简单的改变和各菜单项相或任务栏以及其他控件联系的资源文件文本即可,当改变这些文本后,并不需要改变已生成的头文件中的symbol information,因为使用新文件后我们再重新编译应用程序,并不需要改变那些头文件。它们只是个中间人,具体我们要找的对象变了,我们还是会关注它们的。可以为每种语言都生成一个资源文件,最后实际使用的资源取决于用户安装时的选择。

本地化字符串=

本地化的字符串不要定义在资源文件中,我们可以把它们定义在一个单独的.rls文件中,一个.rls中对字符串定义了各自的symbolic identifers,如下:

//String localised for UK
rls_string STRING_r_example_first_menu_name "Hello"
rls_string STRING_r_example_item0 "Item 0"


在每个字符串定义前都要有关键字rls_string,后面跟着一个symbolic identifer,接着是放在引号中的具体字符串,要把字符串变成German语言,使用同样的identifer,如下:

// Strings localised for German
rls_string STRING_r_example_first_menu_name "Hallo"
rls_string STRING_r_example_item0 "Eintrag 0"


资源文件都是一样的,不管什么本地化不本地化,它只使用指向字符串的symbolic名称,如:

MENU_TITLE
{
menu_pane=r_example_first_menu;
txt=STRING_r_example_first_menu_name;
}


这里定义了一个菜单标题资源,里面有一个标题字符串,这是用

STRING_r_example_first_menu_name(即,"Hello" in UK, "Hallo" in German).


创建本地化资源

具体过程可以分为下面三个步骤:

  • 为每个supported locale都决定一个symbolic identifier(指示标识)
  • 在工程定义文件中指定supported locales
  • 在资源文件中,使用#include 为supported locales包含.rls文件。

下面逐个讨论:

本地化定义

你可以为每个支持的语言指定一个标识,这个标识形式如下: LANGUAGE_language-code


这里的language-code有2个字符长。 你应该使用标准的2位数字来表示(这已经定义在symbian中的TLanguage中—在e32std.h里),里面如ELangGerman(德语)在TLanguage中值为3,这样你可以使用LANGUAGE_03作为标识来标识德语。


你也可以使用字符来标识各语言,如US英语可以标识为LANGUAGE_US,如法语则可以标识为LANGUAGE_FR。

项目文件定义

对连带本地化资源的工程来说,有必要在.mmp文件中使用lang语句以指定语言代码的使用,如果你里面包含有德文(03)和UK英文(01),lang语言可为: lang 01 03


当工程被编译后,在工程文件中指定的每个资源文件都将被编译多次——为每个指定的语言版本。语言的代码将用做编译后资源文件的后缀名:如我们的例子中,最后就会生成两个文件:project-name.r01和project-name.r03。


资源源文件

语言标识可以用来进行有条件的编译,用来指定为各语言生成相应的字符串,在这里列子里为:

// Conditional compile, depending on locale
#ifdef LANGUAGE_01 // if language code is for UK
#include "01-strings.rls"
#elif defined LANGUAGE_03 // if language code is for German
#include "03-strings.rls"
#endif
// end conditional compile


当编译时为01时,就是lang 01 03中的01被认证后,则UK英文字符串01-strings.rls就会编译进这个资源文件中。 当编译时为03时,就是lang 01 03中的03被认证后,则UK英文字符串03-strings.rls就会编译进这个资源文件中。

总的来说由mmp指定包含几种语种的资源,由rss具体指定操作,里面要配合如一,不可或缺。


如何载入资源文件

Uikon应用程序框架在应用程序启动时就试图装入工程资源文件,如果资源文件的扩展名为.rsc,则它即被装入。否则,framework会比较系统的本地化设置而试图装入恰当的资源文件,如设置为德文,则资源文件扩展名为.r03的就会被装入,资源文件如由应用程序明确指定装入,要比由framework装入好,我们可以使用BalfUtils::NearestLanguageFile()来查找出有正确语言扩展名的资源文件。

更多的时候,我们在安装时就选择安装一个资源文件。


程序信息文件

概述

应用程序信息文件,其扩展名为.aif文件,用来存储与应用程序相关的数据,这里的信息包括应用程序的:

  • 各种尺寸的icon
  • 所支持语言的标题
  • 拓展性,如嵌入, 隐藏等
  • MIME-type支持属性


aif文件可以用如下几种方法来生成:

  • 通过GUI工具AIF Builder
  • 通过手写一个Aiftool资源文件。


如果你要手写一个Aiftool资源文件:

  • 如果你使用的是C++,你应该指明在abld处理Aiftool的处理,我们可以将AIF关键字安插在你的.mmp文件中,如下:
AIF DDBouncingBall.aif ..\Aif DDBouncingBallAif.rss \
c12 DDBouncingBallIcon.bmp DDBouncingBallIcon_mask.bmp DDBouncingBallIcon_42x22.bmp DDBouncingBallIcon_42x22_mask.bmp


执行命令行Aiftool工具以生成aif文件

我们使用C++reader和writer类来管理存储在aif文件中的数据(其中wirter类是很少使用的)。 程序可以在没有aif文件的状况下运行,在这种情况,一个缺省的图标被使用——一般是一个问号(依小糊涂看不然,缺省的在s60至少不是问号,而是个拼图状的东东:);不支持MIMI类型;不支持embedding;不支持新文件的产生;缺省的标题就是它可执行文件的名字,不过没有扩展名。

下面逐个描述应用程序信息文件的各个属性。

应用程序图标

图标用来标识程序,以及他们相关的文档和文件。 Aif文件允许多个不同尺寸的图标被存储,最适合当前尺寸的图标将被显示,每个尺寸的图标都需要一个bitmap和一个mask bitmap。


应用程序标题

针对多种语言的标题可被存放在一个aif文件中,其中适合当前系统语言的将会被显示,如果没有适合当前系统语言的标题,则.aif文件名将被使用。


<embeddability> 一个应用程序可以被定义为embeddable,not embeddable, or EmbeddableOnly,一个embeddable文件会出现在embeddable list当中,一个拥有EmbeddableOnly属性的文件将只会出现在embeddable list中,而不会出现在shell中。

缺省状态下,是not embeddable的。

<hidden> 一个应用程序可以被定义为Hidden或Not Hidden.这个Hidden属性可以使得应用程序运行在后台中,这样的文件不会出现在shell或embeddable applications list中,但他们在系统任务列表中都是可见的。

缺省情况下,文件是not hidden的。

<new-file> 应用程序可以被定义为Does Not Support New File或Supports New File。The property allows new files to be created from the system screen as well as in the program。

缺省状态下,文件是不支持New File property的。 注意在c++中,这些特性被封装在TApaAppCapability类中。

UIDs, extension and location

应用程序信息文件被存放在应用程序所在的目录,它们一般都有与应用程序(.app)一样的名字,但扩展名为.aif。

和其他文件一样,应用程序信息文件也有一组3个标识UIDs:

  • The first UID identifies the file as a stream store, see KDirectFileStoreLayoutUid, defined in s32file.h
  • The second UID identifies the DLL as an application information store, see KUidAppInfoFile, defined in apadef.h
  • The third UID is identical to the third UID of the associated application

当使用Aiftool来产生.aif文件时,我们只需要指定第三个UID即可,Aiftool自动的插入其他值。


MIME support

Multipurpose Internet Mail Extensions, MIMEs, 定义了用来传送非文本数据的文件格式,如在因特网上的图片,声音和fax。Aiftool资源文件的datatype_list段列出了程序所支持的MIME类型,以及给出类型的优先级支持。 When a file is to be opened, Symbian OS launches the application which has the highest priority support for the selected file type.


有四个有限级类型,一般只使用EDataTypePriorityNormal或EDataTypePriorityLow。如,一个文本编辑程序最适合编辑text/plain文件,这样它针对该文件类型的优先级为EDataTypePriorityNormal。而一个web browser并不是太适合处理text文件的,所以其针对类型的优先级为EDataTypeProrityLow。这两个程序都可以打开text文档,但优先的是text编辑软件。


EDataTypePriorityHigh将仅用在特殊的情况下,如没有其他程序可以处理该特定MIME类型文件时。


EDataTypePriorityLastResort用的就更少了,text编辑器用来显示HTML很糟糕,则可以设置为该类型的EDataTypePriorityLastResort,或不根本不支持该类型。


注意:

  • 如果两个应用程序拥有同样的MIME类型的优先级,则symbianOS会强制执行其中的一个
  • Developers can give users the ability to set their application as the default MIME type launcher, through the user defined mapping API (datastor.h, class CTypeStoreManager).

如何构建一个AIF

概述

下面的列子演示了怎么去生成一个应用程序信息文件,你必须:

  • 生成一个资源定义文件(rss文件)这个文件中包含了一个结构,里面定义了应用程序的UID,标题,图标的数目,capabilities,以及MIME类型支持级别。
  • 生成一个image和mask bitmap以便在shell中标识该程序。

生成资源定义文件

最容易的方法就是拷贝一个现成的资源文件来修改修改,主要是标题,UID,以及图标的数目。大家可以看下面的列子:

#include <aiftool.rh>
 
RESOURCE AIF_DATA
{
// uid
app_uid=0x10004299;
 
// captions
caption_list=
{
CAPTION { code=ELangEnglish; caption="Hello"; },
CAPTION { code=ELangFrench; caption="Bonjour";
};
 
// icons
num_icons=2;
 
// capabilities
embeddability= KAppEmbeddable;
hidden=KAppNotHidden;
newfile= KAppSupportsNewFile;
 
// MIME types
datatype_list=
{
DATATYPE { priority=EDataTypePriorityNormal; type="text/html"; },
DATATYPE { priority=EDataTypePriorityLow; type="text/plain";
};
 


the include file 这里aiftool.rh资源头文件应该放置在每个资源定义文件的顶部,这个文件定义了aif文件的结构,包括所有支持的语言以及默认的aif文件

capabilites。

  1. include <aiftool.rh>

这个aiftool资源头文件存放在标准的c++包含目录:\Epoc32\Include\

UID 这里的UID(0x10004299)是用来标识程序的唯一性数字,同样的UID也定义在工程文件中(mmp)。 开发者可以从symbian developer network website获得未使用的UIDs

Captions 标题是和图标一起显示在shell中的,下面标识标题为英文和法文都准备了:

caption_list=
{
CAPTION { code=ELangEnglish; caption="Hello"; },
CAPTION { code=ELangFrench; caption="Bonjour";
};

Icons 资源定义文件还指明了本程序所使用的图标数目,每个图标都是由一个icon bitmap和一个mask所组成的,在这个列子里,有2个图标,因此图标文件将包含4个bitmaps(关于mask,前面已经讲的很清楚了:) num_icons=2;

Capabilities Capabilities用来表示应用程序是embeddable,not hidden, 以及是否允许从system shell中产生新的文档。

MIME Types datatype_list语句块表明该应用程序是和HTML以及plain text files相联的。

如何编译AIF文件

概述

当你已经产生了一个适当的资源文件和位图后,你必须将这些都编译在一个单独的二进制aif文件中,你可以用如下两个方法:

  • 使用abld来编译
  • 使用命令行工具aiftool和bmconv


使用abld进行编译

使用abld工具编译时,我们需要在mmp工程文件中使用aif语句块,它应该列出目标文件和源文件的路径名,以及bitmaps文件,如

aif hello.aif helloaif.rss icon1.bmp iconmask1.bmp icon2.bmp iconmask2.bmp


指明要在应用程序目录中编译成hello.aif,它是从源文件helloaif.rss中,以及icon1.bmp已经icon2.bmp和他们的相关的mask。注意这里mask bitmap必须紧跟在相关的icon后面。

在工程进行abld操作时才进行aif文件的编译,abld会调用低层的aiftool和bmconv来编译aif文件。这些工具也可以直接使用。


使用aiftool及bmconv编译

位图必须要转化为一个单独的multi-bitmap(.mbm)文件,这使用的是bitmap转换工具bmconv,你需要提供一个bitmap列表给bmconv,注意mask也是必须的。


生成aif文件

Aiftool将编译资源定义文件,这要和mbm文件一起,在aif文件中,如:

aiftool hello hello.mbm


这里使用hello.rss和hello.mbm,然后产生hello.aif。

This page was last modified on 8 May 2013, at 03:02.
33 page views in the last 30 days.
×