下面的文字剪贴自《windows核心编程》第2章。
随着M i c r o s o f t 公司的Wi n d o w s 操作系统在全世界日益广泛的流行,对于软件开发人员来说,
将目标瞄准国际上的各个不同市场,已经成为一个越来越重要的问题。美国的软件版本比国际
版本提前6 个月推向市场,这曾经是个司空见惯的现象。但是,由于各国对Wi n d o w s 操作系统
提供了越来越多的支持,因此就更加容易为国际市场生产各种应用软件,从而缩短了软件的美
国版本与国际版本推出的时间间隔。
Wi n d o w s 操作系统始终不逾地提供各种支持,以帮助软件开发人员进行应用程序的本地化
工作。应用软件可以从各种不同的函数中获得特定国家的信息,并可观察控制面板的设置,以
确定用户的首选项。Wi n d o w s 甚至支持不同的字体,以适应应用的需要。
之所以将这一章放在本书的开头,是因为考虑到U n i c o d e 是开发任何应用程序时要采用的
基本步骤。本书的每一章中几乎都要讲到关于U n i c o d e 的问题,而且书中给出的所有示例应用
程序都是“用U n i c o d e 实现的”。如果你为Microsoft Windows 2000 或Microsoft Windows CE 开发
应用程序,你应该使用U n i c o d e 进行开发。如果你为Microsoft Windows 98 开发应用程序,你必
须对某些问题作出决定。本章也要讲述Windows 98 的有关问题。
2.1 字符集
软件的本地化要解决的真正问题,实际上就是如何来处理不同的字符集。多年来,许多人
一直将文本串作为一系列单字节字符来进行编码,并在结尾处放上一个零。对于我们来说,这
已经成了习惯。当调用s t r l e n 函数时,它在以0 结尾的单字节字符数组中返回字符的数目。
问题是,有些文字和书写规则(比如日文中的汉字就是个典型的例子)的字符集中的符号
太多了,因此单字节(它提供的符号最多不能超过2 5 6 个)是根本不敷使用的。为此出现了双
字节字符集(D B C S ),以支持这些文字和书写规则。
2.1.1 单字节与双字节字符集
在双字节字符集中,字符串中的每个字符可以包含一个字节或包含两个字节。例如,日文
中的汉字,如果第一个字符在0 x 8 1 与0 x 9 F 之间,或者在0 x E 0 与0 x F C 之间,那么就必须观察下
一个字节,才能确定字符串中的这个完整的字符。使用双字节字符集,对于程序员来说简直是
个很大的难题,因为有些字符只有一个字节宽,而有些字符则是两个字节宽。
如果只是调用s t r l e n 函数,那么你无法真正了解字符串中究竟有多少字符,它只能告诉你
到达结尾的0 之前有多少个字节。A N S I 的C 运行期库中没有配备相应的函数,使你能够对双字
节字符集进行操作。但是,Microsoft Visual C++的运行期库却包含许多函数,如_ m b s l e n ,它可
以用来操作多字节(既包括单字节也包括双字节)字符串。
为了帮助你对D B C S 字符串进行操作,Wi n d o w s 提供了下面的一组帮助函数(见表2 - 1 )。
前两个函数CharNext 和Char Prev 允许前向或逆向遍历DBCS 字符串,方法是每次一个字
符。第三个函数IsDBCSLeadByte, 在字节返回到一个两字字节符的第一个字节时将返回
T R U E 。ഊ表2-1 对D B C S 字符串进行操作的帮助函数
函数描述
PTSTR CharNext (PCTSTR pszCurrentChar );返回字符串中的下一个字符的地址
PTSTR CharPrev (PCTSTR pszStart,PCTSTR 返回字符串中的上一个字符的地址
p s z C u r r e n t C h a r );
BOOL IsDBCSLeadByteTRUE(BYTE bTestChar);如果该字节是DBCS 字符的第一个字节,则返回
尽管这些函数使得我们对D B C S 的操作更容易,但还需要,一个更好的方法让我们来看
看U n i c o d e 。
2.1.2 Unicode :宽字节字符集
U n i c o d e 是A p p l e 和X e r o x 公司于1 9 8 8 年建立的一个技术标准。1 9 9 1 年,成立了一个集团机
构负责U n i c o d e 的开发和推广应用。该集团由A p p l e 、C o m p a q 、H P 、I B M 、M i c r o s o f t 、O r a c l e 、
Silicon Graphics, Inc.、S y b a s e 、U n i s y s 和X e r o x 等公司组成(若要了解该集团的全部成员,请
通过网址w w w. U n i c o d e . o rg 查找)。该集团负责维护U n i c o d e 标准。U n i c o d e 的完整描述可以参阅
A d d i s o n We s l e y 出版的《Unicode Standard 》一书(该书可以通过网址w w w. U n i c o d e . o rg 订购)。
U n i c o d e 提供了一种简单而又一致的表示字符串的方法。U n i c o d e 字符串中的所有字符都是
1 6 位的(两个字节)。它没有专门的字节来指明下一个字节是属于同一个字符的组成部分,还
是一个新字符。这意味着你只需要对指针进行递增或递减,就可以遍历字符串中的各个字符,
不再需要调用C h a r N e x t 、C h a r P r e v 和I s D B C S L e a d B y t e 之类的函数。
由于U n i c o d e 用一个1 6 位的值来表示每个字符,因此总共可以得到65 000 个字符,这样,
它就能够对世界各国的书面文字中的所有字符进行编码,远远超过了单字节字符集的2 5 6 个字
符的数目。
目前,已经为阿拉伯文、中文拼音、西里尔字母(俄文)、希腊文、西伯莱文、日文、韩
文和拉丁文(英文)字母定义了U n i c o d e 代码点。这些字符集中还包含了大量的标点符号、
数学符号、技术符号、箭头、装饰标志、区分标志和其他许多字符。如果将所有这些字母和符
号加在一起,总计约达3 5 0 0 0 个不同的代码点,这样,总计65 000 多个代码点中,大约还有一
半可供将来扩充时使用。
这65 536 个字符可以分成不同的区域。表2-2 显示了这样的区域的一部分以及分配给这些
区域的字符。
表2-2 区域字符
1 6 位代码字符16 位代码字符
0 0 0 0 - 0 0 7 F A S C I I 0 3 0 0 - 0 3 6 F 通用区分标志
0 0 8 0 - 0 0 F F 拉丁文1 字符0 4 0 0 - 0 4 F F 西里尔字母
0 1 0 0 - 0 1 7 F 欧洲拉丁文0 5 3 0 - 0 5 8 F 亚美尼亚文
0 1 8 0 - 0 1 F F 扩充拉丁文0 5 9 0 - 0 5 F F 西伯莱文
0 2 5 0 - 0 2 A F 标准拼音0 6 0 0 - 0 6 F F 阿拉伯文
0 2 B 0 - 0 2 F F 修改型字母0 9 0 0 - 0 9 7 F 梵文
目前尚未分配的代码点大约还有29 000 个,不过它们是保留供将来使用的。另外,大约有
6 0 0 0 个代码点是保留供个人使用的。