Locale IDs

Glossary

Suppose your application displays the current date and time on the status bar of the main window. The user is running the English edition of your application on French Windows and has set the country in Control Panel to Dutch (Belgium). Should the date that is displayed on the status bar be in English, French, or Dutch? Most users would expect the date to be in the default language they have selected, which in this case would be Dutch. (The next section, "Default User and System Locales," discusses user and system defaults.) Suppose the user enters a date in a document. Your application saves a SYSTEMTIME structure in the file and displays the date in the document window by calling GetDateFormat with the user's default locale:

int nLen = GetDateFormat(
LOCALE_USER_DEFAULT, // the user's locale, indicated
// in Control Panel
DATE_LONGDATE, // flags passed to this function
*lpSystemTime, // use current system time
pszDateFormat, // format selected by user
pszDate, // for formatted date
nLen); // date buffer length

After the user is finished with the document, she passes it to someone who runs Windows with the locale set to Standard German. When the new user opens the document, should the date now be in German, or should it remain in Dutch?

It makes sense for applications such as Microsoft Word to format the current time for display on the status bar according to user preference. Changing a date that is already part of a document data stream, however, would confuse or frustrate some users. Microsoft Excel 5, for example, changes the currency symbol when the user changes the locale in the Windows Control Panel. Turning £500 (500 British pounds) into L.500 (500 Italian lire) is a very interesting transaction indeed!

It's important to distinguish between the default locale the user has set for the operating system and the language of text in a document. Word, for example, makes language a text property. Just as a user can format a stream of text as bold, italic, or double-spaced, she can format a stream of text as Spanish or German. (See Figure 5-5.)

Figure 5-5 The Language dialog box from Microsoft Word 6 for Windows.

Windows-based applications can indicate the language of a text stream by tagging it with a locale ID. Saving locale IDs in your documents gives your application multilingual flexibility. As the text at the bottom of the dialog box in Figure 5-5 explains, Word will automatically use the spell-checker, the thesaurus, the hyphenation engine, and the grammar-checker associated with the language of the text stream it is checking, if these tools are available. Word also formats dates according to the language of the text stream. If you store locale IDs in your documents, you can send them to API functions to determine date, time, currency, and number formats; to determine sorting behavior; and, as we shall see in Chapter 6, to determine which keyboard layout and fonts to use for entering and displaying text in a particular language.

To create a list of languages such as the one in Figure 5-5, you can call the function EnumSystemLocales and ask for either all the locales the system supports or for only the locales currently installed in the user's system. When evaluating a locale ID stored in a document, you can call the function IsValidLocale to check whether the current system supports the locale and whether the user has installed it. Usually, the only components that need to be installed for a locale are the Windows code page conversion tables. Therefore, a more accurate test might be to call GetLocaleInfo to retrieve the locale's default ANSI code page (ACP), and then to call IsValidCodePage on that value. If the code page is supported but not installed, your application could display a message warning the user that some information stored in the document might not be displayed correctly.

What if your application includes a Tibetan spell engine? Although the Tibetan locale is not currently part of Windows NT or Windows 95, you can tag Tibetan text with a custom language ID. Custom language IDs are described in Chapter 4.