| 订阅 | 在线投稿
分享
 
 
当前位置: 王朝网络 >> c/c++ >> 怎样在程序中利用C++支持多国语言
 

怎样在程序中利用C++支持多国语言

2008-06-01 02:05:39 编辑來源:互联网 繁體版 评论
 
 
  本文以eMule为例,探讨一下多国语言支持的实现。选择emule,因为它的多国语言支持实现的相当好,可以支持动态切换。而且最要害,它是开源的,可以直接通过源码来研究它的实现技术。

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  emule是利用动态加载资源DLL来实现多语言切换的,每一个资源DLL中包含了一份对应某一语言的字符串表。在源码的srchybrid\lang 路径上可以发现一个lang解决方案,其中包含了差不多40个项目,每个项目编译出来都是一个单独的DLL。这些DLL在程序安装时拷贝到指定的目录中。每个DLL里面都是一个大的string table。emule为每一个用到的字符串(大约为1400多个)都指定了一个固定ID,在不同的DLL中这个ID对应了这个字符串的不同语言的翻译版本。这样每当需要这个字串时就通过ID去获取,在当时程序加载的某一特定语言的DLL,就可以取到相应语言的字串。

  英文版本的string table编译在主EXE文件中,这样当某一语言不支持,或DLL文件加载失败时还可以使用英语版本。

  下面我们就看看具体的实现。

  主要实现代码在I18n.cpp文件中。入口函数是void CPReferences::SetLanguage(),这个函数在在void CPreferences::LoadPreferences()函数中被调用,即载入了程序的各种选项后。当程序第一次运行时,在选项文件(即 preferences.ini)中没有内容,SetLanguage函数会根据系统的本地语言设置来加载对应的语言DLL资源,所以我们第一次安装后就是中文,无需设置。这一点我们后面会说到。

  另外在BOOL CPPgGeneral::OnApply()中也调用了该函数,即用户在“选项”窗口中改变了语言选择后。

  在void CPreferences::SetLanguage()函数中,首先调用了static void InitLanguages(const CString& rstrLangDir, bool bReInit = false)函数。这个函数主要是通过遍历“语言”目录(即我们前面说地的,专门用于存放各种语言版本DLL的目录),来初始化静态“语言表” (_aLanguages),这是个静态数组,其中的每一项对应一种支持的语言。凡能找到相应DLL文件的,就在表中标记该语言为支持。

  然后调用static bool LoadLangLib(const CString& rstrLangDir, LANGID lid)来载入相应的语言DLL。这个函数比较简单,通过查“语言表”(_aLanguages),假如要载入的语言是支持的,就加载相应的DLL文件,并将DLL模块句柄存到_hLangDLL中,这也是一个静态变量。我们可以看到假如是英语,是不需要加载的,直接用EXE模块中的资源字符串表。

  假如调用LoadLangLib文件加载指定的语言失败,程序会尝试判定本地系统的语言集,并加载对应的语言,假如加载也失败就使用英语。

  语言文件加载成功后,程序会尝试从中加载一个字串,假如失败,说明可能DLL文件损坏,则再重设语言为英语。英语字串是内置在EXE文件中的,所以是最可靠的。

  至此,加载成功,句柄保存在_hLangDLL静态变量中。

  最后在需要字符串的地方程序通过CString GetResString(UINT uStringID, Word wLanguageID)或CString GetResString(UINT uStringID)函数加载相应的字符串。这个函数的功能很简单,就是从_hLangDLL指定的模块中加载字符串资源。假如_hLangDLL为 NULL就是从当前模块加载,我们前面已经看到了,假如使用英语这个变量的值就是NULL。

  在emule的源码中,几乎每个对话框都实现了一个Localize(void)函数,这个函数就是通过调用GetResString来设置对话框上所有控件的文字。在BOOL CPPgGeneral::OnApply()函数中我们可以看到,在调用CPreferences::SetLanguage函数切换了语言后,会依次调用对话框和窗口的Localize(void)函数,重新设置UI的文字内容。

  最后注重一点,假如你想让应用支持多语言,在设计对话框时要把对话框的Language属性设为“非特定语言”。在“资源”视图中选中相应的对话框节点,再切换到“属性”视图就可以看到这个选项了。假如不设置会出现乱码。
怎样在程序中利用C++支持多国语言
更多内容请看C/C++进阶技术文档专题,或
 
 
 
上一篇《打开C++Builder菜单设计器》
下一篇《C++中对浮点数的格式化显示》
 
 
 
 
 
 
日版宠物情人插曲《Winding Road》歌词

日版宠物情人2017的插曲,很带节奏感,日语的,女生唱的。 最后听见是在第8集的时候女主手割伤了,然后男主用嘴帮她吸了一下,插曲就出来了。 歌手:Def...

兄弟共妻,我成了他们夜里的美食

老钟家的两个儿子很特别,就是跟其他的人不太一样,魔一般的执着。兄弟俩都到了要结婚的年龄了,不管自家老爹怎么磨破嘴皮子,兄弟俩说不娶就不娶,老父母为兄弟两操碎了心...

如何磨出破洞牛仔裤?牛仔裤怎么剪破洞?

把牛仔裤磨出有线的破洞 1、具体工具就是磨脚石,下面垫一个硬物,然后用磨脚石一直磨一直磨,到把那块磨薄了,用手撕开就好了。出来的洞啊很自然的。需要猫须的话调几...

我就是扫描下图得到了敬业福和爱国福

先来看下敬业福和爱国福 今年春节,支付宝再次推出了“五福红包”活动,表示要“把欠大家的敬业福都还给大家”。 今天该活动正式启动,和去年一样,需要收集“五福”...

冰箱异味产生的原因和臭味去除的方法

有时候我们打开冰箱就会闻到一股异味,冰箱里的这种异味是因为一些物质发出的气味的混合体,闻起来让人恶心。 产生这些异味的主要原因有以下几点。 1、很多人有这种习...

 
 
 
  本文以eMule为例,探讨一下多国语言支持的实现。选择emule,因为它的多国语言支持实现的相当好,可以支持动态切换。而且最要害,它是开源的,可以直接通过源码来研究它的实现技术。   emule是利用动态加载资源DLL来实现多语言切换的,每一个资源DLL中包含了一份对应某一语言的字符串表。在源码的srchybrid\lang 路径上可以发现一个lang解决方案,其中包含了差不多40个项目,每个项目编译出来都是一个单独的DLL。这些DLL在程序安装时拷贝到指定的目录中。每个DLL里面都是一个大的string table。emule为每一个用到的字符串(大约为1400多个)都指定了一个固定ID,在不同的DLL中这个ID对应了这个字符串的不同语言的翻译版本。这样每当需要这个字串时就通过ID去获取,在当时程序加载的某一特定语言的DLL,就可以取到相应语言的字串。   英文版本的string table编译在主EXE文件中,这样当某一语言不支持,或DLL文件加载失败时还可以使用英语版本。   下面我们就看看具体的实现。   主要实现代码在I18n.cpp文件中。入口函数是 void CPReferences::SetLanguage() ,这个函数在在 void CPreferences::LoadPreferences() 函数中被调用,即载入了程序的各种选项后。当程序第一次运行时,在选项文件(即 preferences.ini)中没有内容,SetLanguage函数会根据系统的本地语言设置来加载对应的语言DLL资源,所以我们第一次安装后就是中文,无需设置。这一点我们后面会说到。   另外在 BOOL CPPgGeneral::OnApply() 中也调用了该函数,即用户在“选项”窗口中改变了语言选择后。   在 void CPreferences::SetLanguage() 函数中,首先调用了 static void InitLanguages(const CString& rstrLangDir, bool bReInit = false) 函数。这个函数主要是通过遍历“语言”目录(即我们前面说地的,专门用于存放各种语言版本DLL的目录),来初始化静态“语言表” (_aLanguages),这是个静态数组,其中的每一项对应一种支持的语言。凡能找到相应DLL文件的,就在表中标记该语言为支持。   然后调用 static bool LoadLangLib(const CString& rstrLangDir, LANGID lid) 来载入相应的语言DLL。这个函数比较简单,通过查“语言表”(_aLanguages),假如要载入的语言是支持的,就加载相应的DLL文件,并将DLL模块句柄存到_hLangDLL中,这也是一个静态变量。我们可以看到假如是英语,是不需要加载的,直接用EXE模块中的资源字符串表。   假如调用LoadLangLib文件加载指定的语言失败,程序会尝试判定本地系统的语言集,并加载对应的语言,假如加载也失败就使用英语。   语言文件加载成功后,程序会尝试从中加载一个字串,假如失败,说明可能DLL文件损坏,则再重设语言为英语。英语字串是内置在EXE文件中的,所以是最可靠的。   至此,加载成功,句柄保存在_hLangDLL静态变量中。   最后在需要字符串的地方程序通过 CString GetResString(UINT uStringID, Word wLanguageID) 或 CString GetResString(UINT uStringID) 函数加载相应的字符串。这个函数的功能很简单,就是从_hLangDLL指定的模块中加载字符串资源。假如_hLangDLL为 NULL就是从当前模块加载,我们前面已经看到了,假如使用英语这个变量的值就是NULL。   在emule的源码中,几乎每个对话框都实现了一个Localize(void)函数,这个函数就是通过调用GetResString来设置对话框上所有控件的文字。在  BOOL CPPgGeneral::OnApply() 函数中我们可以看到,在调用CPreferences::SetLanguage函数切换了语言后,会依次调用对话框和窗口的Localize(void)函数,重新设置UI的文字内容。   最后注重一点,假如你想让应用支持多语言,在设计对话框时要把对话框的Language属性设为“非特定语言”。在“资源”视图中选中相应的对话框节点,再切换到“属性”视图就可以看到这个选项了。假如不设置会出现乱码。 [url=http://www.wangchao.net.cn/bbsdetail_1785355.html][img]http://image.wangchao.net.cn/it/1323423780048.gif[/img][/url] 更多内容请看C/C++进阶技术文档专题,或
󰈣󰈤
 
 
 
  免责声明:本文仅代表作者个人观点,与王朝网络无关。王朝网络登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
赏心悦目的模特儿(9)
赏心悦目的模特儿(8)
赏心悦目的模特儿(7)
赏心悦目的模特儿(6)
周六一日游--绿野翠蜂场(一)
骆驼峰
下一站上环
杂乱的几张Danang
 
>>返回首页<<
 
 
 为你推荐
 
 
 
 转载本文
 UBB代码 HTML代码
复制到剪贴板...
 
 热帖排行
 
 
 
 
©2005- 王朝网络 版权所有