.Net Compact Framework 基础篇(10)--多语言程序的定制
很多时候,一款软件不仅仅只是一套语言环境,如果针对不同国家的人,各写一套软件来发布,明显不现实。
如何实现多语言呢?我相信看完这篇文章后,一定会对你有所帮助.
全球化过程力图确保您的应用程序可以处理来自不同文化的数据。它可能会非常简单,如确保您的日历标题足够宽以便能够处理夏威夷月份名称,或者使用您的用户所期望的负数格式。
全球化不同于本地化,后者实际上是将应用程序的资源翻译为不同的语言。即使只使用一种语言,您的应用程序也需要考虑全球化问题。
CultureInfo 对象是使用某种特定文化标识符创建的。例如,为了创建一个在中国区域设置中使用时包含有关中国区域设置信息的对象,您会在构造函数中指定名称 "zh-ch"。Framework 包括许多有关文化的信息,Windows 还包含用于各种区域设置的数据。除此之外,用户还可以创建他们自己的自定义文化。
如果您打算将您的应用程序本地化为多种语言,具体该怎么办?此过程可能涉及 System.Globalization 中处理的所有数据显示功能,以及应用程序各个部件的翻译。您可能还打算针对不同的文化显示不同的图像。为此,您可以制作应用程序的多个副本,每个都对应一个本地化目标语言。
Framework 提供了一种方法,它可以通过 System.Resources 命名空间中的某些类来提取这些可本地化的资源。用于创建、读取和使用这些资源的主类分别是 ResourceWriter、ResourceReader 和 ResourceManager。
ResourceReader 类允许您枚举资源文件中成对的名称/值。但是,最常见的工作通常是针对某一特定文化来查找特定的资源。这是通过 ResourceManager 类实现的。您可以使用 GetObject 和 GetString 方法访问单独的资源,或者也可以使用 GetResourceSet 方法将某一特定文化的所有资源加载到 Hashtable 中。
在下面的Demo中,将列出目前设备中所支持的语言。然后选择一个语言后,界面会根据选择的语言进行转换。
程序运行后的效果:
当我选择"en-us",点Menu下的Change Language后,窗体的Title已发生变化了。
当我选择"zh-cn",同样操作,也发生变化。
这就是多语言的效果。在实际项目中,可以根据当前UI的语言来取得最初的语言资源。用户也可以在运行中随意切换相应的语言。
具体实现:
2 CultureInfo cInfo = CultureInfo.GetCultureInfo(this.listBox1.SelectedItem.ToString());
3 //通过资源管理器来取得资源,SmartDeviceProject5资源文件中对应的命名空间,Form1表示资源文件名
4 ResourceManager rm = new ResourceManager("SmartDeviceProject5.Form1", Assembly.GetExecutingAssembly());
5 this.Text = rm.GetObject("Form1.Title", cInfo).ToString();
看一下,我的工程中的资源文件:
Form1.zh-cn.resx和Form1.en-us.resx表示2个不同的资源文件,zh-ch表示中文,en-us表示英文。ResourceManager会自动去匹配当前语言所需要的资源文件的。
最后,介绍一个小应用。在.net cf中,是无法取得机器上的所有的资源信息的。只有通过API来取得。
调用EnumSystemLocales来取得资源文件。
private delegate int EnumLocalesHandler(string lpLocaleString);
private static EnumLocalesHandler m_localesDelegate;
private static List<CultureInfo> m_cultures;
private void Form1_Load(object sender, EventArgs e)
{
m_cultures = new List<CultureInfo>();
m_localesDelegate = new EnumLocalesHandler(EnumLocalesProc);
IntPtr fnPtr = Marshal.GetFunctionPointerForDelegate(m_localesDelegate);
int success = EnumSystemLocales(fnPtr, LCID_INSTALLED);
for (int i = 0; i < m_cultures.Count; i++)
{
if (m_cultures[i].Name != "")
this.listBox1.Items.Add(m_cultures[i].Name);
}
}
private static int EnumLocalesProc(string locale)
{
try
{
m_cultures.Add(CultureInfo.GetCultureInfo(int.Parse(locale, NumberStyles.HexNumber)));
}
catch
{
// failed for this locale - ignore and continue
}
return 1;
}
[DllImport("coredll", SetLastError = true)]
private static extern int EnumSystemLocales(IntPtr lpLocaleEnumProc, uint dwFlags);
EnumSystemLocales会遍历取得所有的语言,通过定义委托的方式,来一个个加入到List中。
运行环境:VS2008