Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
Member Area
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Become a Member
-Why sign up!
-Chat Online!
-Indexes NEW!!
-Build your resume
-Find a job
-Post a job
-Resume Search
-Link to us
Visit Embarcadero
Embarcadero Community
System and User Locale vs. System and User UI Language Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
Delphi 3.x
User Rating
No Votes
# Votes
DSP, Administrator
Reference URL:

This sorts out the business of Language IDs and UI Language IDs. Why they are 
different and how to access them.


I became quite confused (easy for me) on the subject of Language ID’s. It turns 
out, that what I failed to realize is that there is really two, potentially 
different, languages IDs on a system. Sure, I knew that there is both a default 
“system” ID and a “user” ID for each defined user on the system but what I didn’t 
know, was that there is also a system and user UI Language ID. 

Windows 32 bit operating systems have a System Locale, which can be retrieved with 
GetSystemDefaultLangID. System This ID determines which bitmap fonts, and OEM, ANSI 
and MAC code pages are defaults for the system. 

Complementing the system locale default is the user locale default that determines 
which settings are used for dates, times, currency, numbers, and sort order as a 
default for each user. The GetUserDefaultLangID retrieves the default value for the 
current user. 

Threads can also have a default locale. New threads default to the default user 
locale but can be changed with SetThreadLocale and retrieved with GetThreadLocale. 
The thread locale determines which settings are used for formatting dates, times, 
currency, numbers, and sort order for the thread. 

Eventually, I realized that there is also separate default User Interface (UI) 
language IDs. These determine the language of menus, dialogs, messages, INF files 
and help files. The System UI Language is retrieved using 
GetSystemDefaultUILanguage, while the user UI language is retrieved using 

Once I finally came to terms with this, not so subtle, distinction between “locals” 
and “UI languages” I realized that what I needed was the user UI language ID 
unfortunately none of my copies of Delphi (including Delphi 6) support either 
GetSystemDefaultUILanguage or GetUseDefaultUILanguage. Even worse, these are 
relatively new API calls and only first appeared with Windows ME and 2000. 

Here is a GetUseDefaultUILanguage I pieced together from various MSDN documents, 
samples, and factoids. This was written with Delphi 6 and supports OSs from Win95 
on up. I’ve only tested it on Windows 2000 so please let me know if it hiccups on 
Win9x and NT. 

Send comments to 

1   // Helper
3   function HrFromWin32(dwErr: DWord): HResult;
4   begin
5     result := HResultFromWin32(dwErr);
6   end;
8   // Helper
10  function HrFromLastWin32Error: HResult;
11  var
12    dw: DWord;
13  begin
14    dw := GetLastError;
15    if dw = 0 then
16      result := E_Fail
17    else
18      result := HrFromWin32(dw);
19  end;
21  // Helper
23  function MAKELANGID(p, s: word): word;
24  begin
25    result := (s shl 10) or p;
26  end;
28  // The good stuff
30  function GetUserDefaultUILanguage: LANGID;
31  type
32    TGetLang = function: LangID;
33    THandle = Integer;
34  var
35    GetLang: TGetLang;
36    wUILang: LANGID;
38    Reg: TRegistry;
39    Handle: THandle;
40  begin
41    wUILang := 0;
42    Osv.dwOSVersionInfoSize := sizeof(Osv);
44    if not GetVersionEx(Osv) then
45    begin
46      OleError(HrFromLastWin32Error);
47    end
48      // Get the UI language by one of three methods, depending on OS
49    else if Osv.dwPlatformId <> VER_PLATFORM_WIN32_NT then
50    begin
51      // Case 1: Running on Windows 9x. Get the system UI language from registry:
52      Reg := TRegistry.Create;
53      try
54        Reg.RootKey := HKEY_USERS;
55        if Reg.OpenKey('.Default\Control Panel\desktop\ResourceLocale', False) then
56        begin
57          wUILang := LangID(Reg.ReadInteger(''));
58          Reg.CloseKey;
59        end;
60      finally
61        Reg.Free;
62      end;
63    end
64    else if (Osv.dwMajorVersion >= 5.0) then
65    begin
66      // Case 2: Running on Windows 2000 or later. Use GetUserDefaultUILanguage
67      // to find the user's prefered UI language
68      Handle := LoadLibrary('kernel32.dll');
69      if Handle <> 0 then
70      begin
71        @GetLang := GetProcAddress(Handle, 'GetUserDefaultUILanguage');
72        if @GetLang <> nil then
73          wUILang := GetLang;
74        FreeLibrary(Handle);
75      end;
76    end
77    else
78    begin
79      // Case 3: Running on Windows NT 4.0 or earlier. Get UI language
80      // from locale of .default user in registry:
81      // HKEY_USERS\.DEFAULT\Control Panel\International\Locale
82      Reg := TRegistry.Create;
83      try
84        Reg.RootKey := HKEY_USERS;
85        if Reg.OpenKey('.Default\Control Panel\desktop\International', False) then
86        begin
87          wUILang := LangID(Reg.ReadInteger('Locale'));
88          Reg.CloseKey;
90          // Special case these to the English UI.
91          // These versions of Windows NT 4.0 were enabled only, i.e., the
92          // UI was English. However, the registry setting
93          // HKEY_USERS\.DEFAULT\Control Panel\International\Locale was set
94          // to the respective locale for application compatibility.
95          if ($0401 = wUILang) or // Arabic
96          ($040D = wUILang) or // Hebrew
97          ($041E = wUILang) then // Thai
98          begin
99            wUILang := MakeLangID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
100         end;
102       end;
103     finally
104       Reg.Free;
105     end;
106   end;
107   result := wUILang;
108 end;

Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10


Share this page
Download from Google

Copyright © Mendozi Enterprises LLC