多语言GUI设计
SDK只提供了英文界面的参考,这肯定是不适合逐渐国际化的市场需求,因此我们进行软件功能设计的很重要的一个任务是开发PMP多国语言显示界面,方便各个地区的用户以母语界面对PMP进行操作。
在GUI语言支持方面,系统可以支持简体中文、繁体中文、英语、日语、韩语、丹麦、荷兰、法语、德语、俄语、西班牙等语言中任意几种语言的组合,可以根据实际产品的需要来选择。GUI上所有的标题、选项、文字提示都能用多国语言显示。在设置窗口添加语言选项,语言切换后就可以进入到所选语言的用户界面中去,这样既方便,又有很大的市场价值。
5.2.1 字符编码介绍
36XX开发平台支持的字符编码方式有[16]:
◆Unicode UTF-16
◆Unicode UTF-8
◆DBCS(Double Byte Character Set)
◆ASCII(American Standard Code for Information Interchange)
Unicode是一种字符编码方法,不过它是由国际组织设计,可以容纳全世界所有语言文字的编码方案。Unicode的学名是"Universal Multiple-Octet Coded Character Set",简称为UCS。UCS可以看作是"Unicode Character Set"的缩写。
Unicode UTF-16是把一个Unicode码的字符用两个字节来表示,是唯一的。Unicode UTF-8跟Unicode UTF-16有些相似,每个字符至少占一字节宽度,可以占1到3个字节。
UTF-8跟UTF-16具体比较如表5-3:
表5-3 UTF-8与UTF-16具体比较
UTF-16编码(16进制) |
UTF-8 字节流(二进制) |
0000 - 007F |
0xxxxxxx |
0080 - 07FF |
110xxxxx 10xxxxxx |
0800 - FFFF |
1110xxxx 10xxxxxx 10xxxxxx |
例如“汉”字的Unicode编码是6C49。6C49在0800-FFFF之间,所以肯定要用3字节模板了:1110xxxx 10xxxxxx 10xxxxxx。将6C49写成二进制是:0110 110001 001001, 用这个比特流依次直接代替模板中的x,得到:11100110 10110001 10001001,即e6 b1 89。
DBCS是一种多字节字符集,每个字符占一个或两个字节。DBCS的每个字符通过代码页(code page)映射到一个唯一的UTF-16字符。在FAT文件系统中短文件名是采用DBCS编码而不是ASCII编码。歌曲中的元数据(如歌词、艺术家)也是采用DBCS编码的。在DBCS编码的字符可以显示前,须转化成UTF-16,通过函数txt_ConvertDbcsToUtf16c((char *)pstringbuf,pstringtitle)就可以。
5.2 .2中英文支持
首先需要将SDK的英文字符串准确翻译成想要的中文语言字符串。Sig ma Tel S DK源程序文件的字符串以DBCS(双字节字符集)编码格式保存,在中文开发环境下,DBCS编码可以完整支持ASCII英文字符和GB2312简体中文字符。下面以语言选择标题为例说明添加中文语言支持的方法。
源程序创建语言选择标题的函数:
rtnStat = uim_widget_Create(&pPopupWidget, WIDGET_CLASS_STRINGLIST, WIDGET_ID_LANGUAGE_LIST, gfx_rect_Make(42,20,70,56), g_Language_List, "Language", NG_TYPE_DBCS);
|
程序中,pPopupWidget指向新建的语言选择窗口,WIDGET_ID_LANGUAGE_LIST 为窗口ID编号,便于查找窗口,gfx_rect_Make用来确定窗口的位置和大小,示例中表示该窗口起点在(42,20),大小为70X56,g_Language_List是具体语言选择项的列表,TXT_STRING_TYPE_DB IS表示用DBCS编码显示字符串“Language ",为了增加中文支持,需要对程序做以下修改:
1、创建一个字符串数组指针pstring_Language[g_Language]指向一组对应的英文和中文字符串,变量g_Language代表语言,g_Language=0表示英文,g_Language=1表示中文。
const char *pstring_Language [g_Langaage]={ “Language”, “语言” };
|
2、 改写创建视频播放标题的函数,将字符串换成字符串数组指针:
uim_widget_Create(&pPopupWidget, WIDGET_CLASS_STRINGLIST, WIDGET_ID_LANGUAGE_LIST, gfx_rect_Make(42,20,70,56), g_Language_List[g_Language], pstring_Language[g_Language], TXT_STRING_TYPE_DBCS);
|
3、在设置界面添加一个语言选项,可以改变g_Language的数值。这样,只要改变全局变量g_Language的数值,就可以在“Language”和“语言”两种语言间切换显示,实现语言选择标题的中英文支持。
中英文界面的开发是比较常用的,已经成为基本的需求,如果要产品更有竞争力就需要在语言支持方面有更深层次的设计。
5.2.3多国语言设计方案
上文选择DBCS编码就可以实现PMP的中英文支持,但是DBCS不是一种统一的字符编码格式,对于同一个DBCS码值,不同语言会给出不同的解释,得到不同的字符。
一个相同DBCS码值在简体中文环境下代表一个汉字,在希腊语中可能代表的是一个希腊字符,而在俄语环境下则成了一个俄文字符,也可能是个乱码、空格、或方框,就是显示不正常。因此,要同时支持多国语言,我们就必须选择为每个字符制定一个全球统一的编码,这种编码就是Unicode编码。Unicode采用两个字节为字符编码,可以表示的字符数为2^16=65535,基本上可以容纳所有的欧美字符和绝大部分的亚洲字符。
现在很多新的编译器已经可以支持Unicode格式的源程序文件,在Windows上面的VC2003和Linux操作系统下的GCC,但是STMP36XX开发平台的编译工具Multi IDE只认普通的ANSI标准文件。所以源程序文件和文本文件一样,当文件中出现了Unicode字符后,文件必须保存为Unicode编码格式,否则就会造成字符识别错误。编译器的缺陷使得我们在设计多语言扩展不能像中英文扩展那样,通过简单改写字符串数组指针实现,我们需要改变策略,设计好自己的应用算法。
应用算法思想:
1、首先需要编写提取字符串的Unicode代码程序。将要用到的所有不同语言的字符串按语言自定义的顺序写入一个文本文件,当然这里需要注意的是文本文件必须是保存为unicode类型,就是文件头两个字节是0XFFFE,再用程序读取每个字符串的Unicode编码,再按照语言选择顺序将字符串的码值保存起来。例如,取得“视频播放”的Unicode代码为:0x89c6,0x9891,0x 4ad,0x653e。
2、再为每一个字符串建立一个宽字符串数组,将步骤1保存下来的码值传递给这个宽字符串数组。例如,“视频播放”的宽字符串数组定义为:
Const wchar_t video_play[5]二{0x89c6, 0x9891, 0x 64ad, 0x653e,0) ;
3、为了便于管理,可以采用建立一个二维宽字符串数组指针SytemString[][Language_num],一维参数代表需要改写的字符串的ID号,二维参数g_Languag表示选择的语言。比如系统支持5种语言,那么Language_num就等于5。
4、根据需求将所有需要改写成多语言的字符串集合起来组成步骤3所描叙的二维宽字符串数组指针,但是我们对其成员的名称定义要有必然要有所意义,比如straaab,表示的意思就是字符串的ID号为aaa,b为所选择的语言代号。
const wchar_t* SytemString [][5]二{ str0000, str0001, str0002, str0003, str0004, str0010, str0011, str0012, str0013, str0014, …………………… );
|
5、36XX开发平台支持字符按照UTF16格式输出,建立起二维宽字符串数组指针SytemString [][5]之后,下面以设置FM模式的字符串为例,将字符串换成二维宽字符串数组指针,比如我们选择的是语言0,其ID号为TUNER_MODE_SET, TUNER_MODE_SET为一个枚举。
rtnStat = uim_widget_Create(&pNewWidget, WIDGET_CLASS_TEXT_WIDGET, 0, gfx_rect_Make(110,100-22,45,15), TXT_STRING_TYPE_UTF16, SytemString [TUNER_MODE_SET][ LANGUAGE0] ); |
5.2.4字符串Unicode代码提取程序算法
从应用实际出发分析易知,解决多国语言界面问题的难点在于编写字符串Unicode代码提取程序。因为所有的字符串翻译完成以后,按照自定义择语言顺序保存在编码类型为unicode格式的文本文件后,再通过程序取得它们的Unicode码值,整个PMP界面应用到的字符串数量众多,字符串又经常可能会需要修改,所以数组的码值就是变化的了,如果采用手工编辑输入的话,这个工作量就非常的大,而且维护起来很麻烦。为此,设计一个unicode码值提取程序的将非常智能,还要完成字符串数组赋值和二维指针定义工作。
提取程序的流程算法:
1、创建一个保存在编码类型为unicode 的SytemString.tx t文本文件;
2、把所有系统界面需要字符串按语言顺序写入,按照下面的格式
#英语 简体中文 西班牙语 德语 ………
“play” “播放” “radiar” “uebertragen” ………
3、读取文本文件SytemString.txt,以“字符码值为标志,在进行取码值之前,我们需要创建两个文件,一个用来保存SytemString[][Language_num],另外一个用来保存字符的对应语言的unicode码值,这样就构造好了字符串unicode码值数组表达式和系统所有字符串二维指针。
4、在完成3以后我们就可以拷贝“后面的码值到我们我们创建的文件中保存,知道再次遇到” ,在SytemString[][Language_num]中也记录下保存码值数组的名字;再接着读下一个。
5.逐个读入,循环下去直到读到文件结束,将可以得到我们需要的在步骤3时创建的文件language.c和language.h两个文本文件。