Internationalization and localization tools


Windows C++ Locale Functions

Internationalization (I18n) Discussion:

These are Win32 functions that access Windows-specific locale settings. The following topics discuss the various locale components and emphasize how they should be used in a Win32 internationalized application. For information on Win32 functions that depend on Windows locale settings, see Locale-Sensitive Windows C++ Functions.

Locale

A locale is a collection of language-related, user-preference information, used by applications to format, sort, and display data. Each operating system has at least one installed locale and often has many locales from which the user may choose.

There are two types of locales that can be used in Win32 applications: the locale associated with the application, modified by the call to setlocale/_wsetlocale/_tsetlocale, and used by the locale-sensitive C library calls; and the Windows-only locale that is referred to as LCID and is passed as an argument to the locale-sensitive Windows API functions. Microsoft recommends that these two forms of locale-handling not be mixed and that future Windows applications exclusively use the LCID form of locale.

Care must be taken to ensure that the correct locale is set prior to calling a locale-sensitive function. This help page discusses the Windows-specific locale-handling components, which consist of the LCID, LANGID,GEOID, string sort order, the Windows multibyte code page, and the functions that depend on them. For information on the more generic C and C++ locale-handling, see Locale-Sensitive Functions.

LCID

LCID is the Win32 locale identifier; a 32-bit value, combining language and sorting identifiers as follows:

+-------------+---------+-------------------------+
|  Reserved | Sort ID|      Language ID      |
+-------------+---------+-------------------------+
31           20 19     16 15                           0   bit

The predefined locale identifiers are:

LOCALE_SYSTEM_DEFAULT which identifies the system default locale; on later versions of Windows, it can be changed via the Control Panel's Default Language setting.
LOCALE_USER_DEFAULT which identifies the locale of the current user; it can be changed via the Control Panel's Default Locale setting.

An application can retrieve these two predefined locale identifiers by calling the GetSystemDefaultLCID and GetUserDefaultLCID functions, respectively.

The Thread Locale is maintained on a per-application thread basis and uses SetThreadLocale and GetThreadLocale to access the value. Initially, the value of the thread locale is set to the value of the user's default locale (i.e. LOCALE_USER_DEFAULT).

To create an LCID, use the MAKELCID macro, which combines a language identifier (see MAKELANGID) and a sort identifier (see Sort Identifier below).

The system default locale (LOCALE_SYSTEM_DEFAULT) specifies the multibyte code page that will be used by the Windows operating system to interpret all multibyte strings. In the case of the older operating systems where the native encoding is not Unicode, such as Win 95/98/Me, the multibyte code page must match the UI language of the application - whether the application is Unicode (using Microsoft Layer for Unicode to run on these older Windows systems) or MBCS (uses one multibyte character set). In the case of later versions of Windows that use Unicode as their native encoding, such as Win NT/2K/XP, the system code page is only used when interfacing with non-Unicode applications (e.g. MBCS applications), in order to convert the program's multibyte text to Unicode. Note that on these native-Unicode systems, only applications that do not use Unicode as their default character-encoding mechanism are affected by this setting; applications that are already Unicode-encoded can safely ignore the value and functionality of the system's multibyte code page.

I18n Recommendation
In an international application, the locale identifier should be determined by the application, and then passed into all Win32 functions that perform locale-sensitive formatting or sorting. For example, GetDateFormat would format the date based on the application's LCID value.

Microsoft recommends that the application locale be the same as the user's default locale setting (i.e. the return from GetUserDefaultLCID) to ensure that the application formats and sorts locale-sensitive data according to the user's settings. However, it may be that the application requires a locale that differs from the user's locale. In this case, a dynamic approach would be to set an LCID variable (or call SetThreadLocale) upon application-entry (by reading from a resource file, selecting from a menu of choices, or even by calling GetUserDefaultLCID), and then use that variable (or call GetThreadLocale) throughout the program.

LANGID

LANGID is the Win32 language identifier for a country or geographic region, and consists of a 16-bit value that combines primary and sublanguage identifiers as follows:

+------------------------------+------------------------------+
|     SubLanguage ID        |  Primary Language ID   |
+------------------------------+------------------------------+
15                                 10 9                                    0   bit

The predefined locale identifiers are:

LANG_SYSTEM_DEFAULT which identifies the system default language; it can be changed via the Control Panel's Language setting.
LANG_USER_DEFAULT which identifies the language of the current user; it can be changed via the Control Panel's Locale setting.

An application can retrieve these language identifiers by calling the GetSystemDefaultLangID and GetUserDefaultLangID functions, respectively.

In addition, GetSystemDefaultUILanguage and GetUserDefaultUILanguage are supported on Windows 2K/XP/Me. The System default UI language is the installed language or the localized operating system language; the User default UI language is the user's current language. The user UI language determines the default language of menus and dialog boxes, messages, INF files, and help files. For example, your English application that is running under an operating system with Japanese UI language will bring up Japanese common dialog boxes, Japanese message boxes, and Japanese system error messages. The user's UI language setting can be changed if the system supports a MUI (multilingual) version of the operating system.

To create a LANGID, use the MAKELANGID macro.

I18n Recommendation
In an international application, the language identifier should be determined by the application and then used to retrieve resources, such as strings and images. Note that this value could be different from the language associated with the locale identifier that is used for formatting dates, times, currencies, and numbers, and for sorting strings. This may or may not be desirable, and will need to be considered carefully when designing the application.

In an application that supports resources for multiple languages, Microsoft recommends that this identifier be based on the user's UI language (i.e. return from GetUserDefaultUILanguage), if supported. On systems that don't support GetUserDefaultUILanguage, such as Win 95/98/NT, the resource language identifier could be based on the return from GetSystemDefaultLangID. However, in the scenario where an application supports a specific language or set of languages, a best practice would be to set a LANGID variable upon application-entry (by reading from a resource file, selecting from a menu, or even by calling GetUserDefaultUILanguage), and then use that dynamically-set variable throughout the program.

Sort Identifier

The Sort Identifier is part of the Locale Identifier LCID and determines how strings should be sorted. The default constant for this identifier is SORT_DEFAULT, but other values can be used as shown in the Sort Identifiers table.

I18n Recommendation
As mentioned above under LCID, in an internationalized application, the locale identifier value that contains the sort identifier, should come from a resource file or set dynamically at the start of the program, rather than hard-coding reliance on System defaults.

GEOID

GEOID is the Win32 geography identifier that defines the country or location where the user lives. It is only supported on Windows XP, Windows Server 2003, and Windows ME (though not Windows 2K). The setting can be changed via the Regional Options tab of the Regional And Language Options property sheet.

I18n Recommendation
The function GetUserGeoID can be used to retrieve the setting within an application.

Multibyte Code Page

The multibyte code page is used by both the multibyte C-runtime library functions and the locale-sensitive Win32 functions. As mentioned above under LCID, the system default locale (return from GetSystemDefaultLCID) determines the system's multibyte code page, and will be used by the system for text to Unicode conversion required when running non-Unicode applications.

I18n Recommendation
Care must be taken to ensure that the application's UI language is supported by the target system, and that if the system's multibyte code page is used, it matches the multibyte code page being used by the application. In a Windows MBCS application, the code page must correspond with the language of the application, as it will be used by the various C and C++ string functions. Use setmbcp to set the application's multibyte code page.

See Microsoft Code Page for more information.

Click on a function for more information:

ConvertDefaultLocale

GetACP

GetCPInfo/GetCPInfoEx

GetGeoInfo

GetLocaleInfo

GetOEMCP

GetSystemDefaultLangID

GetSystemDefaultLCID

GetSystemDefaultUILanguage

GetThreadLocale

GetUserDefaultLangID

GetUserDefaultLCID

GetUserDefaultUILanguage

GetUserGeoID

MAKELANGID

MAKELCID

SetLocaleInfo

SetThreadLocale

SetUserGeoID

 

 Locale-Sensitive C++ Methods

 

Lingoport internationalization and localization services and software