MFC 国际化(多国语言)

1:

原文:

http://www.cnblogs.com/xianyunhe/archive/2011/09/02/2163842.html

 

目前很多软件都是要出口到多个国家,因此,为软件提供多国语言支持就成为了一个基本条件。为软件提供多国语言的支持的具体实现方法有很多,但基本原理都差不多,就是实现代码和语言包的独立,代码根据设定的语言选择语言包。

其中,MFC的资源文件就提供了对多国不同语言的支持功能,如果使用MFC开发,直接用资源文件自带的多国语言支持,可以省去不少的麻烦。

下面就介绍给MFC程序添加中英文的支持,开发环境为VS2010。

1.  新建工程

新建了一个对话框工程,工程名称为MultiLanguages,默认语言选择是“中文”。

2.  添加多国语言的资源

在创建工程后,工程会添加默认的资源,如主对话框,都是“中文”资源。现在我们需要添加相应的英文的资源文件。

为主窗口IDD_MULTILANGUAGES添加英文资源的方法为:

(1)       打开Resource View窗口。

(2)       右键IDD_MULTILANGUAGES,点击弹出菜单中的“Insert Copy”菜单,如下图所示。

MFC 国际化(多国语言)

(3)       弹出窗口资源复制语言选择窗口,选择语言为“英语(美国)”,如下图所示。

MFC 国际化(多国语言)

(4)       点击OK,即完成英文版对话框的添加。完成添加后,IDD_MULTILANGUAGES就对应于两个不同语言版本的对话框了,如下图所示。

MFC 国际化(多国语言)

使用同样的方法,也可以为其他资源添加多国语言版本的支持。主要需要多国版本需要支持的有对话框、菜单和字符串。

添加多国语言的资源后,要对这些资源进行不同语言的定制,根据资源对应的语言,设置对话框和控件的标题等。

3.  Locale

程序的语言选择跟操作系统语言(System Locale)、用户设置语言(User Locale)和线程语言(Thread Locale)有关。程序运行时,是根据线程语言来选择资源的。如果程序中未对线程语言进行设置,线程语言默认采用用户设置语言。设置线程语言的函数是SetThreadLocale。

设置线程语言为“中文”的代码如下:

SetThreadLocale(MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT));

 

设置线程语言为“英语(美国)”的代码如下:

SetThreadLocale(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT));

 

设置线程语言要在对话框创建之前,否则无法更改对话框的资源。可以在CMultiLanguagesApp::InitInstance函数中的对话框初始化之前添加线程语言设置,分别设置为中文和英文语言,就可以查看到对话框界面的不同。

4.  字符串处理

程序的多国语言的支持,不仅包括界面的多国语言支持,也要包括各类字符串的多国语言支持,如弹出的提示信息。因此,在弹出提示信息时,也要为提示信息创建多个语言版本,并根据当前线程的语言来选择不同的提示信息。

例子:实现不同语言版本中按钮的点击次数的统计。

(1)       在String Table中分别添加中英文的IDS_STRING_SAMPLE资源,内容如下表所示。

中文

这个一个中文提示信息。\n点击次数:%d。

英文

This is a prompt message in English.\nClick Times:%d.

 

(2)       在主窗口控件中添加一个控件Button1,控件的中文名为“提示”,英文名称为“Prompt”。为该控件添加一个左键单击消息响应函数,该函数的内容如下:

void CMultiLanguagesDlg::OnBnClickedButton1()

{

         // TODO: Add your control notification handler code here

         static int s_iClickTime = 0;

         s_iClickTime++;

         CString strPrompt = _T("");

         CString strFormat = _T("");

         strFormat.LoadString(IDS_STRING_SAMPLE);

         strPrompt.Format(strFormat, s_iClickTime);

         AfxMessageBox(strPrompt);

(3)       分别在CMultiLanguagesApp::InitInstance添加设置线程语言为中文和英文的代码,然后多次点击按钮进行测试。

中文版本弹出的提示框如下图所示:

MFC 国际化(多国语言)

英文版本弹出的提示框如下图所示:

MFC 国际化(多国语言)

5.  语言切换

窗口在初始化时候就导入了资源文件,在通过SetThreadLocale更换了线程语言后,窗口的资源并不会更改,必须要通过代码来重新装载资源。因为窗口中存在多种与线程语言相关的资源,重新启动软件一种叫快捷的更新语言环境的方法。

例:通过菜单来进行语言切换,切换语言后重启软件。

(1)    为程序添加中英文菜单选项ID_LANGUAGE_SWITCH,并为该菜单添加消息响应函数,其中,m_bRestartFlag使用判断关闭窗口时是否需要重启程序的标识。代码如下。

void CMultiLanguagesDlg::OnLanguageSwitch()

{

         // TODO: Add your command handler code here

         // 读取当前线程的语言,并根据当前线程语言进行语言切换

         LCID lcidNew = GetThreadLocale();

         if (LANG_ENGLISH == PRIMARYLANGID(LANGIDFROMLCID(lcidNew)))

         {

                   lcidNew = MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT);

         }

         else

         {

                   lcidNew = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);

         }

 

         // 把语言设置写入配置文件

         CFile file;

         file.Open(_T("Language.ini"), CFile::modeWrite | CFile::modeCreate | CFile::typeBinary);

         file.Write(&lcidNew, sizeof(lcidNew));

         file.Close();

 

         // 关闭窗口

         m_bRestartFlag = TRUE;

         PostMessage(WM_CLOSE, 0, 0);

}

 

(2)    在关闭窗口时,重启动该程序。即在窗口响应WM_CLOSE时,重启程序。代码如下:

void CMultiLanguagesDlg::OnClose()

{

         // TODO: Add your message handler code here and/or call default

         // 判断是否需要重新启动窗口

         if (m_bRestartFlag)

         {

                   CString strFileName = _T("");

                   GetModuleFileName(NULL, strFileName.GetBuffer(MAX_PATH), MAX_PATH);

                   ShellExecute(NULL, _T(""), strFileName, NULL, NULL, SW_SHOWNORMAL);

                   strFileName.ReleaseBuffer();

         }

 

         CDialogEx::OnClose();

}

 

(3)    在启动软件时,根据当前软件的配置文件中语言来设置线程语言,即在CMultiLanguagesApp::InitInstance函数中创建对话框之前设置线程语言,代码如下:

         // 判断你是否存在配置文件,如果存在,从配置文件中读取语言设置

         CString strFileName = _T("Language.ini");

         if (PathFileExists(strFileName))

         {

                   LCID lcidThread = 0;

                   CFile file;

                   file.Open(strFileName, CFile::modeRead | CFile::typeBinary);

                   file.Read(&lcidThread, sizeof(LCID));

                   file.Close();

                   SetThreadLocale(lcidThread);

         }

 

(4)       通过点击菜单来测试软件的语言切换。

6. MessageBox的问题

由于MessageBox中的按钮的语言是跟操作系统相关的,要想实现MessageBox按钮的多语言化是很有一定难度的。我现在还没有查到好的解决方法,很多网友的建议是抛弃MessageBox,自己建立对话框。

  7. 源代码

源代码的下载链接如下:

http://files.cnblogs.com/xianyunhe/MultiLanguages.rar

 

8. 相关函数和类型

与本地化相关的函数和类型如下:

 GetSystemDefaultLCID

GetSystemDefaultLocaleName

GetUserDefaultLCID

GetUserDefaultLocaleName

SetThreadLocale

GetThreadLocale

 

MAKELCID

MAKELANGID

LCIDToLocalName

LocalNameToLCID

LANGIDFROMLCID

PRIMARYLANGID

 

LCID

LANGID

LANG_CHINESE 0x04

LANG_ENGLISH 0x09

2: 

原文:https://blog.csdn.net/changshiyzj/article/details/83086462 
第1章代码页

1 代码页

代码页也叫字符集,它有两个特点:

1、它是一个字符集合;

2、为了便于计算机处理。这个字符集合里,每个字符都有编码。

可用一个字符串表示代码页,如:GB2312、GBK、GB18030、Big5……也可以用一个整数表示代码页,如:20936表示GB2312、936表示GBK、54936表示GB18030、950表示Big5……

1.1 单字节字符集

代码页里,每个字符使用一个字节编码,这样的字符集就是单字节字符集SBCS(Single-byte Character Sets)

1.2 双字节字符集

代码页里,每个字符最多使用两个字节编码,这样的字符集就是双字节字符集DBCS(Double-byte Character Sets)

1.3 多字节字符集

代码页里,某些字符的编码超过了一个字节,这样的字符集就是多字节字符集MBCS(Multi-byte Character Sets)。显然,双字节字符集属于多字节字符集,反过来多字节字符集不一定是双字节字符集。因为,有些代码页会用两个以上的字节表示一个字符。如:UTF-7、UTF-8……。

笔者发现一个规律:Windows中,编码超过两个字节的代码页,其数值超过50000,如下图所示:

图1.1

上图中,除了代码页"51949(EUC-朝鲜语)",剩下超过50000的代码页,其编码用到的最大字节数均大于二。

1.4 ANSI代码页

ANSI代码页具有如下特点:

1、编码0至127符合ANSI(American National Standards Institute——美国国家标准学会)制定的ASCII编码标准;

2、它是由微软制定并实现的。如:GB2312也符合第1条,但它不是ANSI代码页,因为这套编码属于中国的国标,不是微软制定的。由微软实现的GBK才是ANSI代码页;

3、它是双字节字符集,亦即编码最多两个字节。

下图中,有ANSI标志的就是ANSI代码页。简体中文Windows,使用的代码页是936,即GBK。

图1.2

2 枚举代码页

可使用API函数EnumSystemCodePages,枚举系统的代码页。下面的代码枚举代码页,存入变量s_mapCodePage中:

static std::map<UINT,CString> s_mapCodePage;

 

static BOOL CALLBACK EnumCodePagesProc(LPTSTR lpString)

{

s_mapCodePage[_tcstoul(lpString,NULL,10)];

return TRUE;

}

 

{//枚举代码页,存入s_mapCodePage

s_mapCodePage.clear();

EnumSystemCodePages(EnumCodePagesProc,CP_INSTALLED);

}

3 查询代码页信息

可使用GetCPInfoEx函数获得代码页的信息。代码如下:

{//遍历s_mapCodePage,获取每个代码页的说明

CPINFOEX ci;

for(std::map<UINT,CString>::iterator it = s_mapCodePage.begin()

;it != s_mapCodePage.end();++it)

{

if(GetCPInfoEx(it->first,0,&ci))

{

it->second = ci.CodePageName;

}

}

}

结构CPINFOEX里,多字节编码的信息不全——只有首字节的范围信息,没有其它字节的范围信息。

可以通过编码找出其余字节的范围信息。思路就是:调用WideCharToMultiByte函数,将0~0xFFFF的UTF-16编码转换为指定代码页的编码,并确定各个字节的范围。如下图所示,计算出了GBK的编码范围:

图1.3

注意:

1、上图中,一字节的编码范围为[0x00,0xFF],最多只能有256个。何以有41198个之多?原因在于WideCharToMultiByte将UTF-16字符映射为GBK字符时,会有多个字符映射为同一个字符的情况;

2、上图的编码范围只显示最小值和最大值,还不足够精细;

3、实现上述功能的VC++代码已被笔者上传至git服务器,网址如下:

https://github.com/hanford77/Exercise

https://git.oschina.net/hanford/Exercise

在工程WinNLS里。

4 宽窄字符串

Windows 下,使用VC++编程。会遇到三类字符串:

1、宽字符串,即UTF-16编码的字符串。每个字符固定占用两个字节。处理宽字符串的API函数一般以W结尾,如:CreateWindowW、MessageBoxW……

2、窄字符串,即字符串中的字符均属于某个ANSI代码页。每个字符占用一至两个字节。处理窄字符串的API函数一般以A结尾,如:CreateWindowA、MessageBoxA……

3、多字节字符串,即字符串中字符编码的字节数超过了两个。如:UTF-8、GB18030……这类字符串必须转换为宽字符串或窄字符串后,才能被Windows API使用。

Windows系统中,宽字符串不会产生歧义——它总是UTF-16编码;多字节字符串(包括窄字符串)在不同的代码页下会有不同的解释,所以必须明确窄字符串所属的代码页,否则就会产生乱码。

5 字符串转换

宽窄字符串的转换由WideCharToMultiByte(宽字符串转换为多字节字符串)和MultiByteToWideChar(多字节字符串转换为宽字符串)完成。

5.1 查表

WideCharToMultiByte和MultiByteToWideChar的实质工作主要就是查表。如下面的代码转换宽字符串"编码"为窄字符串:

char szStr[64];

WideCharToMultiByte(CP_ACP,0,L"编码",-1,szStr,64,NULL,NULL);

这一行代码做了什么?查看注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage

图1.4

根据上图可知:CP_ACP表示代码页936。再根据936可以查到文件c_936.nls。nls文件其实就是UTF-16编码与ANSI编码的对照表。具体请参考博文:

http://demon.tw/copy-paste/nls-file-format.html

WideCharToMultiByte根据c_936.nls文件中的对照表,把"编码"由UTF-16编码转换为代码页为936的编码。

5.2 NlsDllCodePageTranslation

有些编码不适合查表,如:UTF-7编码与UTF-16编码的转换并不是简单的字符对应关系,无法查表完成。

编码超过两个字节的,无法查表。如:GB18030、UTF-8的编码均超过了两个字节,无法使用nls文件存储编码对照表。

这类情况下,WideCharToMultiByte和MultiByteToWideChar是如何实现的呢?查看注册表,代码页54936(GB18030)对应的文件是c_g18030.dll。

图1.5

在C:\Windows\System32和C:\Windows\SysWOW64目录下,均能找到c_g18030.dll这个文件。System32目录下是64位的,SysWOW64目录下是32位的。这个dll文件,导出了函数NlsDllCodePageTranslation。

图1.6

也就是说,对于无法查表完成的编码转换。WideCharToMultiByte和MultiByteToWideChar会LoadLibrary该代码页对应的dll文件,然后调用该dll文件里的导出函数NlsDllCodePageTranslation,完成编码的转换工作。

 

 

第2章区域

2.1 一个例子

首先看一个例子

#include <stdio.h>

void main()

{

puts ( "窄字符串");

_putws(L"宽字符串");

}

运行结果如下:

图2.1

为什么宽字符串没有被显示出来?因为调用C函数之前,没有设置C函数的代码页为GBK。为此,修改代码如下:

#include <stdio.h>

#include <locale.h>

void main()

{

setlocale(LC_ALL,".936"); //设置代码页为 GBK

puts ( "窄字符串");

_putws(L"宽字符串");

}

运行结果如下:

图2.2

2.2 setlocale

MSDN里关于setlocale函数的说明,第二个参数有些复杂,如下所示:

locale :: "lang[_country[.code_page]]"

| ".code_page"

| ""

| NULL

2.2.1 简单用法

用法

示例

说明

".code_page"

setlocale(LC_ALL,".936");

设置代码页为936

"" 

setlocale(LC_ALL,"");

设置代码页为系统默认值

对于简体中文而言就是936

NULL 

setlocale(LC_ALL,NULL);

获取设置,如:

setlocale(LC_ALL,"");之前调用setlocale(LC_ALL,NULL);将返回"C"

setlocale(LC_ALL,"");之后调用setlocale(LC_ALL,NULL);将返回"Chinese (Simplified)_People's *.936"

2.2.2 复杂用法

setlocale(LC_ALL,"");之后调用setlocale(LC_ALL,NULL);将返回"Chinese (Simplified)_People's *.936"。这个返回值就是"lang[_country[.code_page]]"——下划线之前的是语言,下划线与小数点之间的是国家或地区,小数点之后的是代码页。

语言、国家或地区这两个参数该怎么填?可使用EnumSystemLocales函数枚举Windows系统的区域,然后使用GetLocaleInfo函数获得区域的属性。如下图所示:

图2.3

上图第一列的LCID是EnumSystemLocales函数枚举出来的;LOCALE_SCOUNTRY、LOCALE_SENGLANGUAGE、LOCALE_SENGCOUNTRY……这些列是GetLocaleInfo函数获得的。

根据上图所示,使用setlocale函数设置*地区,可以这样设置:

setlocale(LC_ALL,"Chinese (Traditional)_*.950");

"语言_国家或地区.代码页"比较麻烦,可以使用缩写。缩写可由GetLocaleInfo(...,LOCALE_SABBREVLANGNAME)获得,如下图所示:

图2.4

根据上图所示,使用setlocale函数设置*地区,可以这样设置:

setlocale(LC_ALL,"CHT");

注意:

1、"Uzbek (Cyrillic)_Uzbekistan.1251"与"Uzbek (Latin)_Uzbekistan.1254"的缩写均为UZB。为防止混淆,请不要使用缩写;

2、更多的区域信息,可运行WinNLS程序获得,该程序已被笔者上传至git服务器,网址如下:

https://github.com/hanford77/Exercise

https://git.oschina.net/hanford/Exercise

2.3 #pragma setlocale

还是这段代码,在繁体中文操作系统下编译,会发生什么?

#include <stdio.h>

#include <locale.h>

void main()

{

setlocale(LC_ALL,".936"); //设置代码页为 GBK

puts ( "窄字符串");

_putws(L"宽字符串");

}

首先,这段代码是在简体中文操作系统下编写的,并保存为ANSI编码格式。因此,"窄字符串"和"宽字符串"在源文件中被存储为多字节字符串,代码页为936 GBK。

编译器在编译"窄字符串"时,保持字符串的内容,因此"窄字符串"的编码仍为GBK编码;编译器在编译"宽字符串"时,需要将窄字符串转换为宽字符串。窄字符串的代码页本来是936的,结果在繁体中文操作系统下,VC++编译器会把该字符串的代码页当做950,然后转换为宽字符串。结果就会产生乱码了。

为此,可添加一行代码,如下所示:

#include <stdio.h>

#include <locale.h>

void main()

{

setlocale(LC_ALL,".936"); //设置代码页为 GBK

puts ( "窄字符串");

#pragma setlocale(".936")

_putws(L"宽字符串");

}

#pragma setlocale(".936")的含义就是:让编译器执行一下函数setlocale(...,".936");将代码页切换为936。这样,在将"宽字符串"转换为宽字符串时,就不会产生乱码了。

#pragma setlocale的参数,可以完全按照setlocale函数第二个参数的格式进行填写。

2.4 rc 文件

资源文件(*.rc)同样需要设置区域和代码页,具体如下

LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED

#pragma code_page(936)

LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED指定区域的LCID为0x0804(十进制的2052)。参考图2.4,就是设置区域为"*"。

#pragma code_page(936) 就是设置代码页为936。具体就是:从这一行开始,所有的字符串均是GBK编码。

注意:VC++.NET的rc文件可以保存为Unicode(UTF-16LE)格式。此时,设置区域和代码页似乎不是必需的了。

2.5 排序

LCID里还包含了排序信息。根据这个排序设置,可使用CompareString函数比较两个字符串。

将有排序信息的LCID设置给ComboBox、ListBox,则会影响这些控件的排序功能(其内部应该是调用了CompareString函数),具体请参考WinNLS工程。
--------------------- 
作者:奔流的江 
来源:CSDN 
原文:https://blog.csdn.net/changshiyzj/article/details/83086462 
版权声明:本文为博主原创文章,转载请附上博文链接!

3:Language Identifier Constants and Strings

https://docs.microsoft.com/zh-cn/windows/desktop/Intl/language-identifier-constants-and-strings

Each language identifier is composed of a primary language identifier indicating the language, and a sublanguage identifier indicating the country/region. The language identifier corresponds to a particular locale, for example, English (United States), represented as "en-US". The language identifier is used as part of the locale identifier.

A primary or sublanguage identifier can be user-defined or predefined. The table included in this topic defines the predefined primary language identifiers with their valid sublanguage identifiers.

 备注

If there is no sublanguage identifier to use with a primary language identifier, your application should use SUBLANG_DEFAULT. It should use SUBLANG_NEUTRAL for resources that are the same for all sublanguages of a primary language.

A user-defined primary language identifier has a value in the range 0x0200 to 0x03ff. All other values are reserved for operating system use.

A user-defined sublanguage identifier has a value in the range 0x20 to 0x3f. All other values are reserved for operating system use.

Language identifier Primary language Prim. lang. identifier Prim. lang. symbol Sublanguage Sublang. identifier Sublang. symbol
0x0C00 Default custom locale language 0x00 LANG_NEUTRAL Default custom sublanguage 0x03 SUBLANG_CUSTOM_DEFAULT
0x1400 Default custom MUI locale language 0x00 LANG_NEUTRAL Default custom MUI sublanguage 0x05 SUBLANG_UI_CUSTOM_DEFAULT
0x007F Invariant locale language 0x7F LANG_INVARIANT Invariant sublanguage 0x00 SUBLANG_NEUTRAL
0x0000 Neutral locale language 0x00 LANG_NEUTRAL Neutral sublanguage 0x00 SUBLANG_NEUTRAL
0x0800 System default locale language 0x02 LANG_SYSTEM_DEFAULT System default sublanguage 0x02 SUBLANG_SYS_DEFAULT
0x1000 Unspecified custom locale language 0x00 LANG_NEUTRAL Unspecified custom sublanguage 0x04 SUBLANG_CUSTOM_UNSPECIFIED
0x0400 User default locale language 0x00 LANG_USER_DEFAULT User default sublanguage 0x01 SUBLANG_DEFAULT
0x0436 Afrikaans (af) 0x36 LANG_AFRIKAANS South Africa (ZA) 0x01 SUBLANG_AFRIKAANS_SOUTH_AFRICA
0x041C Albanian (sq) 0x1c LANG_ALBANIAN Albania (AL) 0x01 SUBLANG_ALBANIAN_ALBANIA
0x0484 Alsatian (gsw) 0x84 LANG_ALSATIAN France (FR) 0x01 SUBLANG_ALSATIAN_FRANCE
0x045E Amharic (am) 0x5E LANG_AMHARIC Ethiopia (ET) 0x01 SUBLANG_AMHARIC_ETHIOPIA
0x1401 Arabic (ar) 0x01 LANG_ARABIC Algeria (DZ) 0x05 SUBLANG_ARABIC_ALGERIA
0x3C01       Bahrain (BH) 0x0f SUBLANG_ARABIC_BAHRAIN
0x0C01       Egypt (EG) 0x03 SUBLANG_ARABIC_EGYPT
0x0801       Iraq (IQ) 0x02 SUBLANG_ARABIC_IRAQ
0x2C01       Jordan (JO) 0x0B SUBLANG_ARABIC_JORDAN
0x3401       Kuwait (KW) 0x0D SUBLANG_ARABIC_KUWAIT
0x3001       Lebanon (LB) 0x0C SUBLANG_ARABIC_LEBANON
0x1001       Libya (LY) 0x04 SUBLANG_ARABIC_LIBYA
0x1801       Morocco (MA) 0x06 SUBLANG_ARABIC_MOROCCO
0x2001       Oman (OM) 0x08 SUBLANG_ARABIC_OMAN
0x4001       Qatar (QA) 0x10 SUBLANG_ARABIC_QATAR
0x0401       Saudi Arabia (SA) 0x01 SUBLANG_ARABIC_SAUDI_ARABIA
0x2801       Syria (SY) 0x0A SUBLANG_ARABIC_SYRIA
0x1C01       Tunisia (TN) 0x07 SUBLANG_ARABIC_TUNISIA
0x3801       U.A.E. (AE) 0x0E SUBLANG_ARABIC_UAE
0x2401       Yemen (YE) 0x09 SUBLANG_ARABIC_YEMEN
0x042B Armenian (hy) 0x2B LANG_ARMENIAN Armenia (AM) 0x01 SUBLANG_ARMENIAN_ARMENIA
0x044D Assamese (as) 0x4D LANG_ASSAMESE India (IN) 0x01 SUBLANG_ASSAMESE_INDIA
0x082C Azerbaijani (az) 0x2C LANG_AZERI Azerbaijan, Cyrillic (AZ) 0x02 SUBLANG_AZERI_CYRILLIC
0x042C       Azerbaijan, Latin (AZ) 0x01 SUBLANG_AZERI_LATIN
0x0445 Bangla (bn); see note 10 0x45 LANG_BANGLA Bangladesh 0x02 SUBLANG_BANGLA_BANGLADESH
        India (IN) 0x01 SUBLANG_BANGLA_INDIA
0x046D Bashkir (ba) 0x6D LANG_BASHKIR Russia (RU) 0x01 SUBLANG_BASHKIR_RUSSIA
0x042D Basque (Basque) 0x2d LANG_BASQUE Basque (Basque) 0x01 SUBLANG_BASQUE_BASQUE
0x0423 Belarusian (be) 0x23 LANG_BELARUSIAN Belarus (BY) 0x01 SUBLANG_BELARUSIAN_BELARUS
0x781A Bosnian (bs)   LANG_BOSNIAN_NEUTRAL Neutral    
0x201A Bosnian (bs); see note 2 0x1A LANG_BOSNIAN Bosnia and Herzegovina, Cyrillic (BA) 0x08 SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC
0x141A       Bosnia and Herzegovina, Latin (BA) 0x05 SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN
0x047E Breton (br) 0x7E LANG_BRETON France (FR) 0x01 SUBLANG_BRETON_FRANCE
0x0402 Bulgarian (bg) 0x02 LANG_BULGARIAN Bulgaria (BG) 0x01 SUBLANG_BULGARIAN_BULGARIA
0x0492 Central Kurdish (ku) 0x92 LANG_CENTRAL_KURDISH Iraq (IQ) 0x01 SUBLANG_CENTRAL_KURDISH_IRAQ
0x045C Cherokee (chr) 0x5C LANG_CHEROKEE Cherokee (Cher) 0x01 SUBLANG_CHEROKEE_CHEROKEE
0x0403 Catalan (ca) 0x03 LANG_CATALAN Spain (ES) 0x01 SUBLANG_CATALAN_CATALAN
0x0C04 Chinese (zh); see note 1 0x04 LANG_CHINESE * SAR, PRC (HK) 0x03 SUBLANG_CHINESE_HONGKONG
0x1404       Macao SAR (MO) 0x05 SUBLANG_CHINESE_MACAU
0x1004       Singapore (SG) 0x04 SUBLANG_CHINESE_SINGAPORE
0x0004 Chinese (zh) 0x04 LANG_CHINESE_SIMPLIFIED Simplified (Hans) 0x02 SUBLANG_CHINESE_SIMPLIFIED
0x7C04 Chinese (zh)   LANG_CHINESE_TRADITIONAL Traditional (Hant) 0x01 SUBLANG_CHINESE_TRADITIONAL
0x0483 Corsican (co) 0x83 LANG_CORSICAN France (FR) 0x01 SUBLANG_CORSICAN_FRANCE
0x001A Croatian (hr); see note 2 0x1A LANG_CROATIAN Neutral    
0x101A Croatian (hr) 0x1a LANG_CROATIAN Bosnia and Herzegovina, Latin (BA) 0x04 SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN
0x041A       Croatia (HR) 0x01 SUBLANG_CROATIAN_CROATIA
0x0405 Czech (cs) 0x05 LANG_CZECH Czech Republic (CZ) 0x01 SUBLANG_CZECH_CZECH_REPUBLIC
0x0406 Danish (da) 0x06 LANG_DANISH Denmark (DK) 0x01 SUBLANG_DANISH_DENMARK
0x048C Dari (prs) 0x8C LANG_DARI Afghanistan (AF) 0x01 SUBLANG_DARI_AFGHANISTAN
0x0465 Divehi (dv) 0x65 LANG_DIVEHI Maldives (MV) 0x01 SUBLANG_DIVEHI_MALDIVES
0x0813 Dutch (nl) 0x13 LANG_DUTCH Belgium (BE) 0x02 SUBLANG_DUTCH_BELGIAN
0x0413       Netherlands (NL) 0x01 SUBLANG_DUTCH
0x0C09 English (en) 0x09 LANG_ENGLISH Australia (AU) 0x03 SUBLANG_ENGLISH_AUS
0x2809       Belize (BZ) 0x0A SUBLANG_ENGLISH_BELIZE
0x1009       Canada (CA) 0x04 SUBLANG_ENGLISH_CAN
0x2409       Caribbean (029) 0x09 SUBLANG_ENGLISH_CARIBBEAN
0x4009       India (IN) 0x10 SUBLANG_ENGLISH_INDIA
0x1809       Ireland (IE); see note 3 0x06 SUBLANG_ENGLISH_EIRE
0x1809       Ireland (IE); see note 3 0x06 SUBLANG_ENGLISH_IRELAND
0x2009       Jamaica (JM) 0x08 SUBLANG_ENGLISH_JAMAICA
0x4409       Malaysia (MY) 0x11 SUBLANG_ENGLISH_MALAYSIA
0x1409       New Zealand (NZ) 0x05 SUBLANG_ENGLISH_NZ
0x3409       Philippines (PH) 0x0D SUBLANG_ENGLISH_PHILIPPINES
0x4809       Singapore (SG) 0x12 SUBLANG_ENGLISH_SINGAPORE
0x1c09       South Africa (ZA) 0x07 SUBLANG_ENGLISH_SOUTH_AFRICA
0x2C09       Trinidad and Tobago (TT) 0x0B SUBLANG_ENGLISH_TRINIDAD
0x0809       United Kingdom (GB) 0x02 SUBLANG_ENGLISH_UK
0x0409       United States (US) 0x01 SUBLANG_ENGLISH_US
0x3009       Zimbabwe (ZW) 0x0C SUBLANG_ENGLISH_ZIMBABWE
0x0425 Estonian (et) 0x25 LANG_ESTONIAN Estonia (EE) 0x01 SUBLANG_ESTONIAN_ESTONIA
0x0438 Faroese (fo) 0x38 LANG_FAEROESE Faroe Islands (FO) 0x01 SUBLANG_FAEROESE_FAROE_ISLANDS
0x0464 Filipino (fil) 0x64 LANG_FILIPINO Philippines (PH) 0x01 SUBLANG_FILIPINO_PHILIPPINES
0x040B Finnish (fi) 0x0B LANG_FINNISH Finland (FI) 0x01 SUBLANG_FINNISH_FINLAND
0x080c French (fr) 0x0C LANG_FRENCH Belgium (BE) 0x02 SUBLANG_FRENCH_BELGIAN
0x0C0C       Canada (CA) 0x03 SUBLANG_FRENCH_CANADIAN
0x040c       France (FR) 0x01 SUBLANG_FRENCH
0x140C       Luxembourg (LU) 0x05 SUBLANG_FRENCH_LUXEMBOURG
0x180C       Monaco (MC) 0x06 SUBLANG_FRENCH_MONACO
0x100C       Switzerland (CH) 0x04 SUBLANG_FRENCH_SWISS
0x0462 Frisian (fy) 0x62 LANG_FRISIAN Netherlands (NL) 0x01 SUBLANG_FRISIAN_NETHERLANDS
0x0456 Galician (gl) 0x56 LANG_GALICIAN Spain (ES) 0x01 SUBLANG_GALICIAN_GALICIAN
0x0437 Georgian (ka) 0x37 LANG_GEORGIAN Georgia (GE) 0x01 SUBLANG_GEORGIAN_GEORGIA
0x0C07 German (de) 0x07 LANG_GERMAN Austria (AT) 0x03 SUBLANG_GERMAN_AUSTRIAN
0x0407       Germany (DE) 0x01 SUBLANG_GERMAN
0x1407       Liechtenstein (LI) 0x05 SUBLANG_GERMAN_LIECHTENSTEIN
0x1007       Luxembourg (LU) 0x04 SUBLANG_GERMAN_LUXEMBOURG
0x0807       Switzerland (CH) 0x02 SUBLANG_GERMAN_SWISS
0x0408 Greek (el) 0x08 LANG_GREEK Greece (GR) 0x01 SUBLANG_GREEK_GREECE
0x046F Greenlandic (kl) 0x6F LANG_GREENLANDIC Greenland (GL) 0x01 SUBLANG_GREENLANDIC_GREENLAND
0x0447 Gujarati (gu) 0x47 LANG_GUJARATI India (IN) 0x01 SUBLANG_GUJARATI_INDIA
0x0468 Hausa (ha) 0x68 LANG_HAUSA Nigeria (NG) 0x01 SUBLANG_HAUSA_NIGERIA_LATIN
0x0475 Hawiian (haw) 0x75 LANG_HAWAIIAN United States (US) 0x01 SUBLANG_HAWAIIAN_US
0x040D Hebrew (he) 0x0D LANG_HEBREW Israel (IL) 0x01 SUBLANG_HEBREW_ISRAEL
0x0439 Hindi (hi) 0x39 LANG_HINDI India (IN) 0x01 SUBLANG_HINDI_INDIA
0x040E Hungarian (hu) 0x0E LANG_HUNGARIAN Hungary (HU) 0x01 SUBLANG_HUNGARIAN_HUNGARY
0x040F Icelandic (is) 0x0F LANG_ICELANDIC Iceland (IS) 0x01 SUBLANG_ICELANDIC_ICELAND
0x0470 Igbo (ig) 0x70 LANG_IGBO Nigeria (NG) 0x01 SUBLANG_IGBO_NIGERIA
0x0421 Indonesian (id) 0x21 LANG_INDONESIAN Indonesia (ID) 0x01 SUBLANG_INDONESIAN_INDONESIA
0x085D Inuktitut (iu) 0x5D LANG_INUKTITUT Canada (CA), Latin 0x02 SUBLANG_INUKTITUT_CANADA_LATIN
0x045D       Canada (CA), Canadian Syllabics 0x01 SUBLANG_INUKTITUT_CANADA
0x083C Irish (ga); see note 4 0x3C LANG_IRISH Ireland (IE) 0x02 SUBLANG_IRISH_IRELAND
0x0434 isiXhosa (xh) 0x34 LANG_XHOSA South Africa (ZA) 0x01 SUBLANG_XHOSA_SOUTH_AFRICA
0x0435 isiZulu (zu) 0x35 LANG_ZULU South Africa (ZA) 0x01 SUBLANG_ZULU_SOUTH_AFRICA
0x0410 Italian (it) 0x10 LANG_ITALIAN Italy (IT) 0x01 SUBLANG_ITALIAN
0x0810       Switzerland (CH) 0x02 SUBLANG_ITALIAN_SWISS
0x0411 Japanese (ja) 0x11 LANG_JAPANESE Japan (JP) 0x01 SUBLANG_JAPANESE_JAPAN
0x044B Kannada (kn) 0x4B LANG_KANNADA India (IN) 0x01 SUBLANG_KANNADA_INDIA
______ (reserved) 0x60 LANG_KASHMIRI (reserved) 0x02 SUBLANG_KASHMIRI_INDIA
        (reserved) 0x02 SUBLANG_KASHMIRI_SASIA
0x043F Kazakh (kk) 0x3F LANG_KAZAK Kazakhstan (KZ) 0x01 SUBLANG_KAZAK_KAZAKHSTAN
0x0453 Khmer (kh) 0x53 LANG_KHMER Cambodia (KH) 0x01 SUBLANG_KHMER_CAMBODIA
0x0486 K'iche (qut) 0x86 LANG_KICHE Guatemala (GT) 0x01 SUBLANG_KICHE_GUATEMALA
0x0487 Kinyarwanda (rw) 0x87 LANG_KINYARWANDA Rwanda (RW) 0x01 SUBLANG_KINYARWANDA_RWANDA
0x0457 Konkani (kok) 0x57 LANG_KONKANI India (IN) 0x01 SUBLANG_KONKANI_INDIA
0x0412 Korean (ko) 0x12 LANG_KOREAN Korea (KR) 0x01 SUBLANG_KOREAN
0x0440 Kyrgyz (ky) 0x40 LANG_KYRGYZ Kyrgyzstan (KG) 0x01 SUBLANG_KYRGYZ_KYRGYZSTAN
0x0454 Lao (lo) 0x54 LANG_LAO Lao PDR (LA) 0x01 SUBLANG_LAO_LAO
0x0426 Latvian (lv) 0x26 LANG_LATVIAN Latvia (LV) 0x01 SUBLANG_LATVIAN_LATVIA
0x0427 Lithuanian (lt) 0x27 LANG_LITHUANIAN Lithuanian (LT); see note 5 0x01 SUBLANG_LITHUANIAN_LITHUANIA
0x082E Lower Sorbian (dsb) 0x2E LANG_LOWER_SORBIAN Germany (DE) 0x02 SUBLANG_LOWER_SORBIAN_GERMANY
0x046E Luxembourgish (lb) 0x6E LANG_LUXEMBOURGISH Luxembourg (LU) 0x01 SUBLANG_LUXEMBOURGISH_LUXEMBOURG
0x042F Macedonian (mk) 0x2F LANG_MACEDONIAN Macedonia (FYROM) (MK) 0x01 SUBLANG_MACEDONIAN_MACEDONIA
0x083E Malay (ms) 0x3E LANG_MALAY Brunei Darassalam (BN) 0x02 SUBLANG_MALAY_BRUNEI_DARUSSALAM
0x043e       Malaysia (MY) 0x01 SUBLANG_MALAY_MALAYSIA
0x044C Malayalam (ml) 0x4C LANG_MALAYALAM India (IN) 0x01 SUBLANG_MALAYALAM_INDIA
0x043A Maltese (mt) 0x3A LANG_MALTESE Malta (MT) 0x01 SUBLANG_MALTESE_MALTA
  (reserved) 0x58 LANG_MANIPURI      
0x0481 Maori (mi) 0x81 LANG_MAORI New Zealand (NZ) 0x01 SUBLANG_MAORI_NEW_ZEALAND
0x047A Mapudungun (arn) 0x7A LANG_MAPUDUNGUN Chile (CL) 0x01 SUBLANG_MAPUDUNGUN_CHILE
0x044E Marathi (mr) 0x4E LANG_MARATHI India (IN) 0x01 SUBLANG_MARATHI_INDIA
0x047C Mohawk (moh) 0x7C LANG_MOHAWK Canada (CA) 0x01 SUBLANG_MOHAWK_MOHAWK
0x0450 *n (mn) 0x50 LANG_*N *, Cyrillic (MN) 0x01 SUBLANG_*N_CYRILLIC_*
0x0850       *, Mong (MN) 0x02 SUBLANG_*N_PRC
0x0461 Nepali (ne) 0x61 LANG_NEPALI Nepal (NP) 0x01 SUBLANG_NEPALI_NEPAL
        India (IN) 0x02 SUBLANG_NEPALI_INDIA
0x0414 Norwegian (no) 0x14 LANG_NORWEGIAN Bokmål, Norway (NO) 0x01 SUBLANG_NORWEGIAN_BOKMAL
0x0814       Nynorsk, Norway (NO) 0x02 SUBLANG_NORWEGIAN_NYNORSK
0x0482 Occitan (oc) 0x82 LANG_OCCITAN France (FR) 0x01 SUBLANG_OCCITAN_FRANCE
0x0448 Odia (or) 0x48 LANG_ORIYA India (IN) 0x01 SUBLANG_ORIYA_INDIA
0x0463 Pashto (ps) 0x63 LANG_PASHTO Afghanistan (AF) 0x01 SUBLANG_PASHTO_AFGHANISTAN
0x0429 Persian (fa); see note 6 0x29 LANG_PERSIAN Iran (IR) 0x01 SUBLANG_PERSIAN_IRAN
0x0415 Polish (pl) 0x15 LANG_POLISH Poland (PL) 0x01 SUBLANG_POLISH_POLAND
0x0416 Portuguese (pt) 0x16 LANG_PORTUGUESE Brazil (BR) 0x01 SUBLANG_PORTUGUESE_BRAZILIAN
0x0816       Portugal (PT); see note 7 0x02 SUBLANG_PORTUGUESE
0x0867 Pular (ff) 0x67 LANG_PULAR Senegal (SN) 0x02 SUBLANG_PULAR_SENEGAL
0x0446 Punjabi (pa) 0x46 LANG_PUNJABI India, Gurmukhi script (IN) 0x01 SUBLANG_PUNJABI_INDIA
0x0846       Pakistan, Arabic script(PK) 0x02 SUBLANG_PUNJABI_PAKISTAN
0x046B Quechua (quz) 0x6B LANG_QUECHUA Bolivia (BO) 0x01 SUBLANG_QUECHUA_BOLIVIA
0x086B       Ecuador (EC) 0x02 SUBLANG_QUECHUA_ECUADOR
0x0C6B       Peru (PE) 0x03 SUBLANG_QUECHUA_PERU
0x0418 Romanian (ro) 0x18 LANG_ROMANIAN Romania (RO) 0x01 SUBLANG_ROMANIAN_ROMANIA
0x0417 Romansh (rm) 0x17 LANG_ROMANSH Switzerland (CH) 0x01 SUBLANG_ROMANSH_SWITZERLAND
0x0419 Russian (ru) 0x19 LANG_RUSSIAN Russia (RU) 0x01 SUBLANG_RUSSIAN_RUSSIA
0x0485 Sakha (sah); see note 9 0x85 LANG_SAKHA Russia (RU) 0x01 SUBLANG_SAKHA_RUSSIA
0x243B Sami (smn) 0x3B LANG_SAMI Inari, Finland (FI) 0x09 SUBLANG_SAMI_INARI_FINLAND
0x103B Sami (smj)     Lule, Norway (NO) 0x04 SUBLANG_SAMI_LULE_NORWAY
0x143B       Lule, Sweden (SE) 0x05 SUBLANG_SAMI_LULE_SWEDEN
0x0C3B Sami (se)     Northern, Finland (FI) 0x03 SUBLANG_SAMI_NORTHERN_FINLAND
0x043B       Northern, Norway (NO) 0x01 SUBLANG_SAMI_NORTHERN_NORWAY
0x083B       Northern, Sweden (SE) 0x02 SUBLANG_SAMI_NORTHERN_SWEDEN
0x203B Sami (sms)     Skolt, Finland (FI) 0x08 SUBLANG_SAMI_SKOLT_FINLAND
0x183B Sami (sma)     Southern, Norway (NO) 0x06 SUBLANG_SAMI_SOUTHERN_NORWAY
0x1C3B       Southern, Sweden (SE) 0x07 SUBLANG_SAMI_SOUTHERN_SWEDEN
0x044F Sanskrit (sa) 0x4F LANG_SANSKRIT India (IN) 0x01 SUBLANG_SANSKRIT_INDIA
0x7C1A Serbian (sr); see note 2   LANG_SERBIAN_NEUTRAL Neutral    
0x1C1A   0x1a LANG_SERBIAN Bosnia and Herzegovina, Cyrillic (BA) 0x07 SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC
0x181A       Bosnia and Herzegovina, Latin (BA) 0x06 SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_LATIN
        Croatia (HR) 0x01 SUBLANG_SERBIAN_CROATIA
0x0C1A       Serbia and Montenegro (former), Cyrillic (CS) 0x03 SUBLANG_SERBIAN_CYRILLIC
0x081A       Serbia and Montenegro (former), Latin (CS) 0x02 SUBLANG_SERBIAN_LATIN
0x046C Sesotho sa Leboa (nso) 0x6C LANG_SOTHO South Africa (ZA) 0x01 SUBLANG_SOTHO_NORTHERN_SOUTH_AFRICA
0x0832 Setswana / Tswana (tn) 0x32 LANG_TSWANA Botswana (BW) 0x02 SUBLANG_TSWANA_BOTSWANA
0x0432       South Africa (ZA) 0x01 SUBLANG_TSWANA_SOUTH_AFRICA
  (reserved) 0x59 LANG_SINDHI (reserved) 0x02 SUBLANG_SINDHI_AFGHANISTAN
0x0459 (reserved)     (reserved) 0x01 SUBLANG_SINDHI_INDIA
0x0859 Sindhi (sd)     Pakistan (PK) 0x02 SUBLANG_SINDHI_PAKISTAN
0x045B Sinhala (si) 0x5B LANG_SINHALESE Sri Lanka (LK) 0x01 SUBLANG_SINHALESE_SRI_LANKA
0x041B Slovak (sk) 0x1b LANG_SLOVAK Slovakia (SK) 0x01 SUBLANG_SLOVAK_SLOVAKIA
0x0424 Slovenian (sl) 0x24 LANG_SLOVENIAN Slovenia (SI) 0x01 SUBLANG_SLOVENIAN_SLOVENIA
0x2C0A Spanish (es) 0x0A LANG_SPANISH Argentina (AR) 0x0b SUBLANG_SPANISH_ARGENTINA
0x400A       Bolivia (BO) 0x10 SUBLANG_SPANISH_BOLIVIA
0x340A       Chile (CL) 0x0D SUBLANG_SPANISH_CHILE
0x240A       Colombia (CO) 0x09 SUBLANG_SPANISH_COLOMBIA
0x140A       Costa Rica (CR) 0x05 SUBLANG_SPANISH_COSTA_RICA
0x1C0A       Dominican Republic (DO) 0x07 SUBLANG_SPANISH_DOMINICAN_REPUBLIC
0x300A       Ecuador (EC) 0x0C SUBLANG_SPANISH_ECUADOR
0x440A       El Salvador (SV) 0x11 SUBLANG_SPANISH_EL_SALVADOR
0x100A       Guatemala (GT) 0x04 SUBLANG_SPANISH_GUATEMALA
0x480A       Honduras (HN) 0x12 SUBLANG_SPANISH_HONDURAS
0x080A       Mexico (MX) 0x02 SUBLANG_SPANISH_MEXICAN
0x4C0A       Nicaragua (NI) 0x13 SUBLANG_SPANISH_NICARAGUA
0x180A       Panama (PA) 0x06 SUBLANG_SPANISH_PANAMA
0x3C0A       Paraguay (PY) 0x0F SUBLANG_SPANISH_PARAGUAY
0x280A       Peru (PE) 0x0A SUBLANG_SPANISH_PERU
0x500A       Puerto Rico (PR) 0x14 SUBLANG_SPANISH_PUERTO_RICO
0x0C0A       Spain, Modern Sort (ES) 0x03 SUBLANG_SPANISH_MODERN
0x040A       Spain, Traditional Sort (ES) 0x01 SUBLANG_SPANISH
0x540A       United States (US) 0x15 SUBLANG_SPANISH_US
0x380A       Uruguay (UY) 0x0E SUBLANG_SPANISH_URUGUAY
0x200A       Venezuela (VE) 0x08 SUBLANG_SPANISH_VENEZUELA
0x0441 Swahili (sw) 0x41 LANG_SWAHILI Kenya (KE) 0x01 SUBLANG_SWAHILI
0x081D Swedish (sv) 0x1D LANG_SWEDISH Finland (FI) 0x02 SUBLANG_SWEDISH_FINLAND
0x041D       Sweden (SE); see note 8 0x01 SUBLANG_SWEDISH
0x041D       Sweden (SE); see note 8 0x01 SUBLANG_SWEDISH_SWEDEN
0x045A Syriac (syr) 0x5A LANG_SYRIAC Syria (SY) 0x01 SUBLANG_SYRIAC
0x0428 Tajik (tg) 0x28 LANG_TAJIK Tajikistan, Cyrillic (TJ) 0x01 SUBLANG_TAJIK_TAJIKISTAN
0x085F Tamazight (tzm) 0x5F LANG_TAMAZIGHT Algeria, Latin (DZ) 0x02 SUBLANG_TAMAZIGHT_ALGERIA_LATIN
0x0449 Tamil (ta) 0x49 LANG_TAMIL India (IN) 0x01 SUBLANG_TAMIL_INDIA
0x0849       Sri Lanka (LK) 0x02 SUBLANG_TAMIL_SRI_LANKA
0x0444 Tatar (tt) 0x44 LANG_TATAR Russia (RU) 0x01 SUBLANG_TATAR_RUSSIA
0x044A Telugu (te) 0x4A LANG_TELUGU India (IN) 0x01 SUBLANG_TELUGU_INDIA
0x041E Thai (th) 0x1E LANG_THAI Thailand (TH) 0x01 SUBLANG_THAI_THAILAND
0x0451 * (bo) 0x51 LANG_* PRC (CN) 0x01 SUBLANG_*_PRC
0x0873 Tigrinya (ti) 0x73 LANG_TIGRINYA Eritrea (ER) 0x02 SUBLANG_TIGRINYA_ERITREA
0x0473       Ethiopia (ET) 0x01 SUBLANG_TIGRINYA_ETHIOPIA
0x0873 (reserved) 0x73 LANG_TIGRIGNA (reserved) 0x02 SUBLANG_TIGRIGNA_ERITREA
0x041F Turkish (tr) 0x1F LANG_TURKISH Turkey (TR) 0x01 SUBLANG_TURKISH_TURKEY
0x0442 Turkmen (tk) 0x42 LANG_TURKMEN Turkmenistan (TM) 0x01 SUBLANG_TURKMEN_TURKMENISTAN
0x0422 Ukrainian (uk) 0x22 LANG_UKRAINIAN Ukraine (UA) 0x01 SUBLANG_UKRAINIAN_UKRAINE
0x042E Upper Sorbian (hsb) 0x2E LANG_UPPER_SORBIAN Germany (DE) 0x01 SUBLANG_UPPER_SORBIAN_GERMANY
0x0820 Urdu (ur) 0x20 LANG_URDU (reserved) 0x02 SUBLANG_URDU_INDIA
0x0420       Pakistan (PK) 0x01 SUBLANG_URDU_PAKISTAN
0x0480 * (ug) 0x80 LANG_UIGHUR PRC (CN) 0x01 SUBLANG_UIGHUR_PRC
0x0843 Uzbek (uz) 0x43 LANG_UZBEK Uzbekistan, Cyrillic (UZ) 0x02 SUBLANG_UZBEK_CYRILLIC
0x0443       Uzbekistan, Latin (UZ) 0x01 SUBLANG_UZBEK_LATIN
0x0803 Valencian (ca) 0x03 LANG_VALENCIAN Valencia (ES-Valencia) 0x02 SUBLANG_VALENCIAN_VALENCIA
0x042A Vietnamese (vi) 0x2A LANG_VIETNAMESE Vietnam (VN) 0x01 SUBLANG_VIETNAMESE_VIETNAM
0x0452 Welsh (cy) 0x52 LANG_WELSH United Kingdom (GB) 0x01 SUBLANG_WELSH_UNITED_KINGDOM
0x0488 Wolof (wo) 0x88 LANG_WOLOF Senegal (SN) 0x01 SUBLANG_WOLOF_SENEGAL
0x0478 Yi (ii) 0x78 LANG_YI PRC (CN) 0x01 SUBLANG_YI_PRC
0x046A Yoruba (yo) 0x6A LANG_YORUBA Nigeria (NG) 0x01 SUBLANG_YORUBA_NIGERIA

 

Language Identifier Notes

  1. To set a neutral language, use LANG_CHINESE_SIMPLIFIED or LANG_CHINESE_TRADITIONAL with ConvertDefaultLocale.
  2. Primary language identifiers for Bosnian, Croatian, and Serbian are numerically identical. For Bosnian, use LANG_BOSNIAN with SUBLANG_BOSNIAN_* sublanguage identifiers. For Croatian, use LANG_CROATIANwith SUBLANG_CROATIAN_* sublanguage identifiers. For Serbian, use LANG_SERBIAN with SUBLANG_SERBIAN_* sublanguage identifiers. To set a neutral language, use LANG_BOSNIAN_NEUTRALLANG_CROATIAN, or LANG_SERBIAN_NEUTRAL with ConvertDefaultLocale.
  3. Starting with Windows VistaSUBLANG_ENGLISH_IRELAND supersedes SUBLANG_ENGLISH_EIRE. The numerical values of the constants are identical.
  4. Always use the language identifier constant LANG_IRISH with SUBLANG_IRISH_IRELAND.
  5. Starting with Windows VistaSUBLANG_LITHUANIAN_LITHUANIA supersedes SUBLANG_LITHUANIAN. The numerical values of the constants are identical.
  6. The language identifiers for Farsi and Persian are numerically identical. The constant LANG_FARSI is deprecated. Use LANG_PERSIAN instead.
  7. Starting with Windows VistaSUBLANG_PORTUGUESE_PORTUGAL supersedes SUBLANG_PORTUGUESE. The numerical values of the constants are identical.
  8. Starting with Windows VistaSUBLANG_SWEDISH_SWEDEN supersedes SUBLANG_SWEDISH. The numerical values of the constants are identical.
  9. Starting with Windows 8: The language identifiers for Yakut and Sakha are numerically identical. The constants LANG_YAKUT and SUBLANG_YAKUT_RUSSIA are deprecated. Use LANG_SAKHA and SUBLANG_SAKHA_RUSSIA instead.
  10. The language identifiers for Bengali and Bangla are numerically identical. The constants LANG_BENGALISUBLANG_BENGALI_BANGLADESH, and SUBLANG_BENGALI_INDIA are deprecated. Use LANG_BANGLASUBLANG_BANGLA_BANGLADESH, and SUBLANG_BANGLA_INDIA instead.

4: microsoft  international

https://docs.microsoft.com/zh-cn/windows/desktop/Intl/international-support