[原crybird]
本文纯属个人观点,很多问题还没看到问题的本质,请各位高手、大牛指教。
本文概念基于VC++和Windows。
部分素材来源网络,如有侵权,请联系me :)
允许非商业目的转载,如有转载,请标明[转]字。第一部分:国际化一什么是ID
简单的说,ID本质是一个整数,在不同的场合,具有不同的意义。主要是用来区分群体中的个体,即把群体中的某个个体,抽象成一个整数,在一定范围内使用和识别。二LocalID
如何在世界的众多区域中标识本地区域呢?用LocalID,它是在语言的基础上抽象的一种标识。LocalID是由两个id拼接而成的,LanguageID和SortID。
DWORD MAKELCID(WORD lgid, WORD srtid)三LanguageID
LanguageID也是由两个id拼接而成的,主id和子id。以简体中文为例,此外还要其他语言的主id,和台湾香港澳门等相关的子id。
WORD MAKELANGID(WORD priID, WORD subID)
#define LANG_CHINESE                    0x04
#define SUBLANG_CHINESE_SIMPLIFIED   0x02 
宏处理后,简体中文是0x804四SortID
#define SORT_CHINESE_PRC   0x2 // PRC Chinese Stroke Count order相关宏有:
MAKELCID
LANGIDFROMLCID
SORTIDFROMLCID
MAKELANGID
SUBLANGID
PRIMARYLANGID
LocalID、LanguageID、SorID的相关宏和预定义的值,请参阅包含在winnt.h,也可查阅MSDN。

解决方案 »

  1.   

    第二部分:字符编码一CharSet(字符集):
    字符集(CharSet或者character repertoire)是一组抽象字符(abstract character)的集合,这里的字符是用来表达语义的符号。比如所有汉字构成的字符集,西欧语言字母构成的字符集,符号构成的字符集等。字符集的子集也为字符集,比如所有繁体字的集合。下面是一些字符集的ID,
    #define ANSI_CHARSET 0 (ASCI)
    #define GB2312_CHARSET 134 (中简GB2312)
    #define CHINESEBIG5_CHARSET 136 (中繁BIG5)
    #define SHIFTJIS_CHARSET 128 (日)
    #define HANGUL_CHARSET 129 (韩)
    此外还有阿拉伯、希腊等等。二CodePage(代码页):
    以简体中文为例子,为了计算机查找排序方便,给所有的简体中文和一些符号(按一定的规律和规则)映射一个整数表,表里面的每一个整数对应一个汉字或符号,这个表就是代码页。(这里的整数不约束于四个字节)。
    具体的说,一个字节能表示的范围是0-127,而字符却成千上万个。由于字符个数大大多于一个字节能表示的范围,所以一般用多个字节表示一个字符。(这里的多个字节对应上段内容的整数,定义为“字节串”概念)
    字符集和代码页不一定是一一对应的关系,字符集里面的字符和代码页中的整数也不一定是一一对应的。比如代码页A中可以对应字符集1的中文简体中文和字符集2的英文字母。而代码页B中可以对应所有的简体和繁体中文。
    #define CP_ACP 0 // default to ANSI code page
    #define CP_OEMCP 1 // default to OEM  code page
    #define CP_MACCP 2 // default to MAC  code page
    #define CP_THREAD_ACP 3 // current thread's ANSI code page
    #define CP_SYMBOL 42 // SYMBOL translations
    #define CP_UTF7 65000 // UTF-7 translation
    #define CP_UTF8 65001 // UTF-8 translation
    可以在控制面板-区域和语言中查看自己电脑中安装的CodePage。三什么是编码Encoding
    说明CodePage的时候,所谓的“一定的规律和规则”就是编码。编码的结果就是代码页。
    当前国际上最为通用的字符编码(商业规范)是Unicode编码。Unicode是由一个非赢利性组织“Unicode学术学会”建立和发展的涵盖世界大多数流行语言的字符编码形式。Unicode[现有的标准]版本为4.1,其中包含的所有语言符号(超过9万个,其中汉字为7万多)。
    其他编码:GB2312, GB13000, GB18030, Unicode,UTF-8这些都是对字符集的编码(encoding)。其中常见对汉语字符集的编码包括GB2312-1980, GB13000, GBK, GB12345, GB18030—2000, Big5, Big5+, HKSCS, Big5+HKSCS, CNS 11643-1992等。UCS-2, UCS-4, UTF-32, UTF-16, UTF-8, UTF-EBCDIC和UTF-7都是Unicode编码的具体形式(即它们不是直接映射的字符,而是映射的Unicode码,其实也就对应字符啦)。四多字节编码
    由于字符个数大大多余一个字节能表示的范围,所以一般用多个字节表示一个字符。还以汉字为例子,一个汉字,在这个代码表中用1234表示,在另外一个代码表中可能用56789表示,如何转换呢?先把1234转换成一个标准的编码,然后由标准的编码转换成56789,
    如此转换可以减少转换复杂度。这个“标准”就是上面提到的Unicode。同时用到了以下两个转换的window API:
    MultiByteToWideChar(...)
    WideCharToMultiByte(...)五字体(Font)
    知道“宋体”和“黑体”的区别,就不用解释字体的意义了。
    要注意的是,字体不支持所有的字符。比如说宋体不会支持阿拉伯和梵文。所以要生成字体的时候,要选择字符集。字体里面存的是下笔拐弯和画直线等信息,对应的是文字符号。六乱码的产生和消除
    乱码产生的原因可能原因有:1代码页转换问题2没有应用合适的字体。大多数乱码出现是由于第一个原因,这里只介绍原因1。
    还是拿汉字为例子。比如一个汉字,目前表示对应的是UTF-8编码中的12345。而默认的PageCode是GB2312。当显示汉字的时候,在GB2312中找12345对应的文字,肯定是错误的字或者乱码。如何正确显示呢?首先用MultiByteToWideChar函数把UTF-8编码转换成Unicode编码,再用WideCharToMultiByte函数把Unicode编码转换成GB2312的编码,然后显示才会正确。如下:
    UTF-8 ---- 12345
    Unicode ---- 55555
    GB2312 ---- 98765
    当显示的时候,在GB2312中找98765就会找到UTF-8中12345对应的汉字了。当然,用阿拉伯文字体或者梵文字体还是显示不出正确的字,还是找宋体吧 :)
      

  2.   

    显示汉字的时候,反正只要编码不对,就肯定乱码,这是必然的。不过UTF-8的标准英文字符在ANSI字符集,GB2312的字符集的显示方式下都是正确的!
      

  3.   

    最近正苦恼一件汉化的事,请各位指教:
    在汉化一个unicode编码的大英文软件时,出现两个问题:
    一是有些地方出现乱码,
    二是有几个string table里的条目翻译后运行时点击程序出现崩掉现象
    程序有原代码,c++语言写的,我在vc++6.0下打开资源,把属性设置成中文后(我的系统和vc++都是英文版)开始翻译成中文,菜单翻译后运行正常,翻译几个string table里的条目运行出问题,请高手和有汉化经验的朋友指点!!!谢谢
      

  4.   

    先看一些令人头疼的概念:字符集CharSet、代码页CodePage、编码Encoding、字体Font、ASCI、UNICODE、双字节字符集DBCS、多字节字符集MBCS、GB2312、GBK、UTF8...
      

  5.   

    故事开始了在很久很久以前久以前久以前以前以前
    永远记住,计算机只认识0和1。梦魇开始了
    人类把符号映射成整数,让计算机去处理。最开始的时候,计算机里用一个字节表示所有字符,包括字母、数字和一些符号。最高位置0,所以共包含128个字符。这些定义好的字符组成了ASCI表。后来发现128个字符不够用了,就把最高位也用上了,共包含256个字符,这些字符组成了扩展ASCI表。
    与此同时,中国等一些亚州国家的字符远不止256个,一个字节是不足以表示这些字符的博大精深的。所以,就采用2个字节表示一个字符,同时兼容ASCI。于是GB2312标准字符集产生了,后来又扩展到了GBK,并兼容了香港和台湾的繁体。用两个字节表示一个符号,就是所谓的DBCS(double-byte CharSet)。但是,两个字节最多也仅能容65536个字符,虽然已经足够一般情况用了,可特殊的情况(特殊符号、生僻字等等)总是让人讨厌。而且中国大陆、台湾繁体、韩日等等国家的字符集都是独立定义的,同样两个字节,中文的简体和繁体就可能代表不同的汉字,当进行国际交流的时候,乱码肆虐的时刻来临了
    地球村是越来越小的,有必要让所有村民使用的字符互不干扰,统一成一个公共的字符集。于是Unicode应运走进历史的舞台。用两个字节代表一个符号,而且兼容ASCI表。为了容易数,规定两个字节等于一个宽字符,这样符号的个数和宽字符的个数就一直了。这就是UCS-2。事实证明,他们低估了中国汉字的数量,65535个位置全分配给中国还不够呢,于是又出现了用四个字节表示一个字符的UCS-4。现在把世界上所有语言的符号包进去,都放的下了。(现在最常用的,还是UCS-2)
    不过,没有什么是完美的。Unicode在传输的时候总是有意想不到的差错。还好人类聪明,把Unicode编码改成用不定个字节表示一个符号,可能是一个、两个、甚至六个。这样用来传输是很方便的。于是UTF8、UTF16产生了。这样用多个字节表示一个字符,就是所谓的多字节字符集MBCS(Multi-byte CharSet)。
      

  6.   

    很好的一个帖子 
    楼主有心了
    ASCII码中 一个英文字母占一个字节的空间
              一个中文汉字占两个字节的空间
              英文标点占一个字节
              中文标点占两个字节
    UNICODE码中  每个字符都占两个字节
                 Unicode有着统一的标准,它定义了世界上绝大多数的字符的编码(encoding)
                     使得拉丁文、数字、简体中文、繁体中文、日文等都可以同一种编码方式保存