When you write an application, or any other type of software, you need to take special care when working with characters, strings, numbers, and dates, as different countries represent these items in different ways. This chapter describes how to write code that works properly for any language that is supported by Palm OS®. The chapter covers:
- Localization Guidelines
- Using Overlays to Localize Resources
- Dates
- Numbers
- Obtaining Locale Information
- Notes on the Japanese Implementation
- Summary of Localization
In addition to this chapter, also see Chapter 8, "Text," which describes how to work with text and characters in a way that makes your application easily localizable.
NOTE: PalmOSGlue provides backward compatibility for many of the functions described in this chapter. When a function has a PalmOSGlue equivalent, that equivalent is shown in parentheses following the function name. See "Backward Compatibility with PalmOSGlue" for more information on PalmOSGlue.
This chapter does not cover how to actually perform localization of resources. For more information on this subject, see the Palm OS Programming Development Tools Guide.
Localization Guidelines
If there is a possibility that your application is going to be localized, you should follow these guidelines when you start planning the application. It's a good idea to follow these guidelines even if you don't think your application is going to be localized.
- If you use the English language version of the software as a guide when designing the layout of the screen, try to allow:
- Don't put language-dependent strings in code. If you have to display text directly on the screen, remember that a one-line warning or message in one language may need more than one line in another language. See the section "Strings" in Chapter 8, "Text," for further discussion.
- Don't depend on the physical characteristics of a string, such as the number of characters, the fact that it contains a particular substring, or any other attribute that might disappear in translation.
- Database names must use only 7-bit ASCII characters (0x20 through 0x7E). If an actual PDB name is displayed to the user, the application should have a way of associating a localizable name (resource based, if possible) with each database.
- Use the functions described in this chapter when working with characters, strings, numbers, and dates.
- Consider using string templates as described in the section "Dynamically Creating String Content" in Chapter 8. Use as many parameters as possible to give localizers greater flexibility. Avoid building sentences by concatenating substrings together, as this often causes translation problems.
- Abbreviations may be the best way to accommodate the particularly scarce screen real estate on the Palm Powered™ handheld.
- Remember that user interface elements such as lists, fields, and tips scroll if you need more space.
The book Palm OS User Interface Guidelines provides further user interface guidelines.
Using Overlays to Localize Resources
Palm OS version 3.5 adds support for localizing resource databases through overlays. Localization overlays provide a method for localizing a software module without requiring a recompile or modification of the software. Each overlay database is a separate resource database that provides an appropriately localized set of resources for a single software module (the PRC file, or base database) and a single target locale (language and country).
No requirements are placed on the base database, so for example, third parties can construct localization overlays for existing applications without forcing any modifications by the original application developer. In rare cases, you might want to disable the use of overlays to prevent third parties from creating overlays for your application. To do so, you should include an 'xprf'=0
resource (symbolically named sysResTExtPrefs
) in the database and set its disableOverlays
flag. This resource is defined in UIResources.r
.
An overlay database has the same creator as the base database, but its type is 'ovly'
, and a suffix identifying the target locale is appended to its name. For example, Datebook.prc
might be overlaid with a database named Datebook_jpJP
, which indicates that this overlay is for Japan. Each overlay database has an 'ovly'
=1000 resource specifying the base database's type, the target locale, and information necessary to identify the correct version of the base database for which it was designed.
The Palm OS SDK provides tools that you can use to create overlays. See the "PRC to Overlay Tool" chapter in the Palm OS Programming Development Tools Guide for more information on creating overlays.
When a PRC file is opened on a system that supports overlays, the Overlay Manager determines what the current locale is for this handheld, and it looks for an overlay matching the base database and the locale. The overlay database's name must match the base database's name, its suffix must match the locale's suffix, and it must have an 'ovly'
=1000 resource that matches the base database. If the name, suffix, and overlay resource are all correct, the overlay is opened in addition to the PRC file. When the PRC file is closed, its overlay is closed as well.
The overlay is opened in read-only mode and is hidden from the programmer. When you open a database, you'll receive a reference to the base database, not the overlay. You can simply make Resource Manager calls like you normally would, and the Resource Manager accesses the overlay where appropriate.
When accessing a localizable resource, do not use functions that search for a resource only in the database you specify. For example:
// WRONG! searches only one database. DmOpenRef dbP = DmNextOpenResDatabase(NULL); UInt16 resIndex = DmFindResource(dpP, strRsc, strRscID); MemHandle resH = DmGetResourceIndex(dbP, resIndex);
In the example above, dbP
is a reference to the most recently opened database, which is typically the overlay version of the database. Passing this reference to DmFindDatabase
means that you are searching only the overlay database for the resource. If you're searching for a non-localized resource, DmFindResource
won't be able to locate it. Instead, you should use DmGet1Resource
, which searches the most recently opened database and its overlay for a resource, or DmGetResource
, which searches all open databases and their overlays.
// Right. DmGet1Resource searches both // databases. MemHandle resH = DmGet1Resource(strRsc, strRscID); // Or use DmGetResource to search all open // databases. MemHandle resH = DmGetResource(strRsc, strRscID);
The Data Manager only opens an overlay if the resource database is opened in read-only mode. If you open a resource database in read-write mode, the associated overlay is not opened. What's more, if you modify an overlaid resource in the base database, the checksum in the overlay's 'ovly'
resource becomes invalid, which prevents the overlay from being used at all. Thus if you change the resource database, you must also change the overlay database.
You typically don't work with the Overlay Manager directly although it does provide a few public functions. One potentially useful function is OmGetCurrentLocale
(or OmGlueGetCurrentLocale
), which returns a structure identifying the locale on this handheld.
Dates
If your application deals with dates and times, it should abide by the values the user has set in the system preference for date and time display. The default preferences at startup vary among locales, and the default values can be overridden by the user.
To check the system preferences call PrefGetPreference
with one of the values listed in the second column of Table 12.1. The third column lists an enumerated type that helps you interpret the value.
Table 12.1 Date and time preferences
Time formats (i.e., use a 12-hour clock or use a 24-hour clock) |
||
Minutes east1 of Greenwich Mean Time (GMT), also known as Universal Coordinated Time (UTC). |
||
Before 4.0, the |
1. The previous name of this preference notwithstanding, a positive value indicates minutes east of GMT, while a negative value indicates minutes west of GMT.
|
IMPORTANT: The
prefMinutesWestOfGMT
preference mentioned above is not the same as the prefTimeZone
preference. The prefMinutesWestOfGMT
returns an unsigned value ranging from 0 to 1440. The prefTimeZone
preference ranges from -720 to 720.
To work with dates in your code, use the Date and Time Manager API. It contains functions such as DateToAscii
, DayOfMonth
, DayOfWeek
, DaysInMonth
, and DateTemplateToAscii
, which allow you to work with dates independent of the user's preference settings.
Numbers
If your application displays large numbers or floating-point numbers, you must check and make sure you are using the appropriate thousands separator and decimal separator for the handheld's country by doing the following (see Listing 12.1):
- Store numbers using US conventions, which means using a "," as the thousands separator and a decimal point (.) as the decimal separator.
- Use
PrefGetPreference
andLocGetNumberSeparators
to retrieve information about how the number should be displayed. - Use
StrLocalizeNumber
to perform the localization. - If a user enters a number that you need to manipulate in some way, convert it to the US conventions using
StrDelocalizeNumber
.
Listing 12.1 Working with numbers
// store numbers using US conventions. Char *jackpot = "20,000,000.00"; Char thou; // thousand separator Char dp; // decimal separator // Retrieve user's preferred number format. LocGetNumberSeparators((NumberFormatType) PrefGetPreference(prefNumberFormat), &thou, &dp); // Localize jackpot number. Converts "," to thou // and "." to dp. StrLocalizeNumber(jackpot, thou, dp); // Display string. // Assume inputString is a number user entered, // convert it to US conventions this way. Converts // thou to "," and dp to "." StrDelocalizeNumber(inputNumber, thou, dp);
Obtaining Locale Information
Some applications may require information about the current locale. For example, many applications need to know the format for displaying dates or numbers, which is determined in part by the current locale (and described in more detail in the section "Dates" and "Numbers" in this chapter). Other applications may need other information, such as the country name.
The information that most applications require is stored in the system preferences structure and can be obtained using PrefGetPreference
. This is the recommended way of obtaining locale-specific settings because the user can override many of these settings. Applications should always honor the user's preferences rather than the locale defaults.
Other locale-specific settings can not be set by the user and are not stored in the system preferences. Instead, these settings are stored in a private resource that contains information about several possible locales, including the locale currently used by the system. For example, the user cannot change the symbol used for the local currency. If your application needs this information, it must use the Locale Manager function LmGetLocaleSetting
to retrieve it. The Locale Manager is new in Palm OS 4.0, but for backwards compatibility you can use the corresponding PalmOSGlue function LmGlueGetLocaleSetting
. Listing 12.2 shows how to use LmGlueGetLocaleSetting
.
Listing 12.2 Retrieving a locale setting using Locale Manager
LmLocaleType locale; Char currencySymbol[kMaxCurrencySymbolLen+1]; UInt16 index; // Find out what the current locale is. OmGlueGetCurrentLocale(&locale); // Find out which index in the locale resource // contains info about that locale. LmGlueLocaleToIndex(&locale, &index); // Get the currency symbol stored in the locale at // that index. LmGlueGetLocaleSetting(index, lmChoiceCurrencySymbol, currencySymbol, sizeof(currencySymbol));
Table 12.2 shows which types of information about the current locale should be retrieved from the system preferences and which types should be retrieved from the locale resource. Of course, if you want to retrieve information about a different locale or if you want to look up the default used for the current locale, you would always use the Locale Manager instead of the Preferences Manager.
Table 12.2 Obtaining locale information
Notes on the Japanese Implementation
This section describes programming practices for applications that are to be localized for Japanese use. It covers:
- Japanese Character Encoding
- Japanese Character Input
- The Calculator Button
- Displaying Japanese Strings on UI Objects
- Displaying Error Messages
Japanese Character Encoding
The character encoding used on Japanese systems is based on Microsoft code page 932. The complete 932 character set (JIS level 1 and 2) is supported in both the standard and large font sizes. The bold versions of these two fonts contain bolded versions of the glyphs found in the 7-bit ASCII range, but on some handhelds, the single-byte Katakana characters and the multi-byte characters are not bolded.
Japanese Character Input
On current Japanese handhelds, users enter Japanese text using Latin (ASCII) characters, and special software called a front-end processor (FEP) transliterates this text into Hiragana or Katakana characters. The user can then ask the FEP to phonetically convert Hiragana characters into a mixture of Hiragana and Kanji (Kana-Kanji conversion).
Figure 12.1 Input area on a Japanese handheld

Japanese handhelds have four additional buttons that control the FEP transliteration and conversion process. These four FEP buttons are arranged vertically between the left-most icons and the handwriting recognition area. The top-most FEP button tells the FEP to attempt Kana-Kanji conversion on the inline text. The next button confirms the inline text and terminates the inline conversion session. The third button toggles the transliteration mode between Hiragana and Katakana. The last button toggles the FEP on and off.
Japanese text entry is always inline, which means that transliteration and conversion happen directly inside of a field. The field code passes events to the FEP, which then returns information about the appropriate text to display.
During inline conversion, the Graffiti® or Graffiti® 2 space stroke acts as a shortcut for the conversion FEP button and the return stroke acts as a shortcut for the confirm FEP button.
The Calculator Button
On current Japanese handhelds, the Calculator silkscreen button doesn't generate a calcChr
. Instead, it generates a keyDown
event with the event's data.keyDown.chr
field set to keyboardChr
and it's data.keyDown.modifiers
field set to commandKeyMask
.
Displaying Japanese Strings on UI Objects
To conserve screen space, you should use half-width Katakana characters on user interface elements (such as buttons, menu items, labels, and pop-up lists) whenever the string contains only Katakana characters. If the string contains a mix of Katakana and either Hiragana, Kanji, or Romaji, then use the full-width Katakana characters instead.
Displaying Error Messages
You may have code that uses the macros ErrFatalDisplayIf
and ErrNonFatalDisplayIf
to determine error conditions. If the error condition occurs, the system displays the file name and line number at which the error occurred along with the message that you passed to the macro. Often these messages are hard-coded strings. On Japanese systems, the Palm OS traps the messages passed to these two macros and displays a generic message explaining that an error has occurred.
You should only use ErrFatalDisplayIf
and ErrNonFatalDisplayIf
for totally unexpected errors. Do not use them for errors that you believe your end users will see. If you wish to inform your users of an error, use a localizable resource to display the error message instead of ErrFatalDisplayIf
or ErrNonFatalDisplayIf
.
Chinese Fonts
Some Chinese fonts—especially 9 point on a standard display—use all of the available vertical space. Because of this the layout of form elements might need to be tweaked for proper vertical spacing.
Summary of Localization
OmGetCurrentLocale |
OmGetSystemLocale |