How to localise resources

Overview

Symbian developers can localise a C++ application by simply changing the resource file text associated with each menu item, task bar or other control. Since changes to the text do not change the symbol information in the generated header file, it is not necessary to recompile the application to use the new file. Consequently, a resource file may be generated for each language supported, and the actual resource used is determined by the end-user at installation time.

The examples quoted in this page are taken from the code example Examples\ToolsAndUtilities\Localise, which provides the Hello World application, localised for English and German.

Localisable strings

Localisable strings should not be defined within a resource file, but in separate files with the extension .rls. An .rls file defines symbolic identifiers for strings, to which the resource file refers when it needs the associated string.

An example from an .rls file is shown below:

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

The keyword rls_string appears before each string definition, followed by a symbolic identifier, and then the string itself in quotes. To localise the file for German, the same identifiers would be used, but the strings would be translated, i.e.

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

The resource file itself would be the same, whatever the locale, as it would only refer to strings through their symbolic names, e.g.

MENU_TITLE
    {
    menu_pane=r_example_first_menu;
    txt=STRING_r_example_first_menu_name;
    }

defines a menu title resource, with a title string defined by STRING_r_example_first_menu_name (i.e. "Hello" in UK, "Hallo" in German).

Building localised resource files

You can define in a project definition (.mmp) file the locales that the project supports. Given appropriate resource source and .rls files, the build process then builds a separate compiled resource file for each supported locale.

The process in detail can be broken into three steps:

  • determine on a symbolic identifier for every supported locale

  • specify in the project definition file the supported locales

  • #include the .rls files for the supported locales in the resource source file

These are discussed further below.

Locale identifiers

You should decide on a symbolic identifier for every supported language. The symbol should be of the form:

LANGUAGE_ language-code

where language-code should be two characters long, but otherwise can be anything you like, as long as each language in the resource file has a unique symbol.

You are recommended to use a standard two-digit number as defined by Symbian in an enumeration TLanguage in e32std.h, which gives numeric values to the languages. For example, the value ELangGerman (German) in TLanguage has the value 3, so you could use LANGUAGE_03 as the symbol for German.

Alternatively, you can use logical letters for each language: e.g. US English might have the symbol LANGUAGE_US, while French might have the symbol LANGUAGE_FR.

Project definition files

For projects with localised resources, you must use the lang statement in the .mmp file to set the languages codes used. So, for the above example, in which the language codes used are for German (03) and UK English (01), the lang statement should read:

lang 01 03

When the project is built, each resource file specified in the project file will be compiled multiple times, once for each language-code specified. The language codes are used to complete the extension of the built resource files: for our example, two files would be built: project-name .r01 and project-name .r03.

Resource source files

The symbols can then used, with conditional compilation statements, to specify which string definitions should be compiled for each language. In the example code fragment below, the file 01-strings.rls is assumed to have the strings localised for UK English, and the file 03-strings.rls the strings localised for German.

// 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
  • when built with the code 01, the UK English strings in 01-strings.rls are compiled into the resource file

  • when built with the code 03, the German strings in 03-strings.rls are compiled into the resource file

How programs load resource files

The Uikon application framework attempts to load the project's resource file when the application starts up. If the resource file has the extension .rsc, then this is loaded. Alternatively, the framework attempts to load the correct resource file by comparing the system locale setting with the available resource files: for example, in a German locale, the resource file with extension .r03 would be loaded. Resource files that are explicitly loaded by programs, rather than by the framework, can use the same stategy, by calling BalfUtils::NearestLanguageFile() to find a resource file with the correct language extension.

More typically than installing all the resource files for all the available locales, you would only want to select a single resource file for installation, based on the system locale or user preference. The Symbian platform Installation System enables this, as described in PKG file format to support multilingual application installation.