VC-MFC不像.Net框架,它没有提供直接的多语言国际化开发支持。在网上找了很多的资料,总结出来有两种解决方案:1. 纯资源方案,即把多种语言的界面资源编译成多个dll,程序运行时通过动态加载dll资源文件来更改界面语言。
2. 外挂字典方案,即把程序中所有的显示信息(字符串)存储在一个文本文件中,程序运行时加载字串,通过GetWndItem(ID)->SetWindowText()的方法更改界面。显然,纯资源方案同时要维护多份资源,解决数据一致性问题。而外挂字典个人觉得更加合理一点。但是具体要怎么实现这个方案我一点底都没有,请各位高手指点。我的初步设想是:
字典文件存储“标识串,(具体某个国家)信息字串”对。程序初始化时,把文件的所有“标识串->字串”对加载到内存中,为了加快查找速度,用哈希表(如CMap<CString,CString>或STL的map<>)来存储。在程序中再维持一个哈希表,存储从资源ID到标识的“ID->标识串”对。这样,切换语言界面时,可以通过资源ID快速查找标识串,再找到具体国家的显示信息,更新到Windows对象中去。但这个方法也有很多问题:
1. 内存中一直存储着两份表,如果程序大,可能会耗去很多内存。因为程序一启动就加载,到用户结束程序时,可以有很多对话框都没打开过,浪费了很多内存。
2. 菜单资源的弹出项(顶级项,如“文件”)设置不了ID。
3. 对话框中的静态文本默认都是同一个ID值,要一个个改,而且CStatic对象的宽度在多种语言中的宽度也不一样,不好设置。VB和BC中是用字串来标识一个资源的(一个哈希表搞定),但在VC中用ID,所有只有维持两个表才能实现。不知各位高手还有没有其它的解决方案,请指教!!

解决方案 »

  1.   

    如果说纯资源DLL需要维护多份语言资源,存在什么数据一致性问云云,那么外挂字典文件里,就不需要维护多份语言资源了?还不是一样吗?应该说,纯资源DLL是实现起来最方便的一种方案,用VS直接做编辑器,是我们最熟悉的。而假如你使用MFC扩展DLL,则更是在程序里除了LoadLibrary就不需要做其他额外事情了。纯资源DLL唯一的,也是难以超越的问题就是没法实现动态切换界面语言。只能是重新启动程序时,在创建窗口之前,先加载一个资源DLL。字典方案是相当麻烦的,除非你的界面不实现动态切换语言就不能满足需求,否则我是不推荐使用字典方式的--假如你的界面的最终用户基本不会切换语言,或者只是在安装完后设定一次语言,而你却为此编写了大量代码,修改了大量Bugs的话,你想想有多不值?字典方式中,首要任务就是设计一种字典格式,第一使之能够完整表述你的语言、界面系统。例如一般情况下都至少需要“语言 \ 窗口 \ 控件ID”三层分支。有些人喜欢用不同文件来做“语言”分支。第二要非常方便查询。比如,如果你的字典文件里面一条文本记录占一行,格式为“en-us|dialog_32001|ctrl_1001 = &Open File”,这样的记录显然肯定会使你的查询非常困难。用XML是最好最方便的。实现字典方式,是 不 应 该 把所有字符串加载到内存中的。有什么用呢?在窗口创建时已经通过SetWindowsText将字符串写入窗口对象里了,自己再保存一份的话,可能直到窗口关闭都再也用不上一次了。动态切换时,就再从文件里读取一次即可。不过总之,这个话题细说起来就比较话长了。
      

  2.   

    多谢AgedBOY的建议,我会好好考虑的。
    现在想来,用外挂字典方案真的比较麻烦。
    但公司要求用户能自行更改语言或显示习惯,如在医学领域,一个技术词可能存在着不同的叫法,每个医院都可能用自己的用语习惯。DLL加载显然不现实。把字典加载到内存,的确很浪费。但程序不是只有一个主对话框,还有很多对话框是动态在栈中创建的。另外,像程序中有很多MessageBox()显示的消息也不可能一次设置完毕。所以,如果不先把字典加载到内存,并且操作经常是打开/关闭对话框,那么读取文件可能很频繁,而且文件查找字串的速度也不敢恭维。
      

  3.   

    各位大虾好,我是个初学者,现在正在做一个多语言的VC程序,能不能麻烦哪位给我发一个多语言的小程序,万分感谢,[email protected]