在使用MultiByteToWideChar的时候,大部分都知道上述两个参数,MSDN的解释如下:
先解释CodePage的意思:
请注意,在不同的计算机上,即使在同一个网络上,这个值也会有所不同。它可以在同一台计算机上的改变,导致存储的数据变得不可恢复的破坏。这个值只供临时使用和永久存储应尽可能使用UTF-16或UTF-8。
CP_ACP:
而在使用W2A的时候,系统默认调用的是CP_THREAD_ACP,这个配置应该是调用USES_CONVERSION;时候获取到Windows当前线程代码页,这样转化后如果区域和语言的格式选项设置成英文以及其他语言文字的时候,在转化中文时候会输出乱码
而W2A_CP函数提供了使用系统默认的Windows ANSI代码页
代码页Code Page
微软为了适应世界上不同地区用户的文化背景和生活习惯,在Windows中设计了区域(Locale)设置的功能。Local是指特定于某个国家或地区的一组设定,包括代码页,数字、货币、时间和日期的格式等。在Windows内部,其实有两个Locale设置:系统Locale和用户Locale。系统Locale决定代码页,用户Locale决定数字、货币、时间和日期的格式。我们可以在控制面板的“区域和语言选项”中设置系统Locale和用户Locale:
每个Locale都有一个对应的代码页。Locale和代码页的对应关系,大家可以参阅我的另一篇文章《谈谈Windows程序中的字符编码》的附录1。系统Locale对应的代码页被作为Windows的默认代码页。在没有文本编码信息时,Windows按照默认代码页的编码方案解释文本数据。这个默认代码页通常被称作ANSI代码页(ACP)。
ANSI代码页还有一层意思,就是微软自己定义的代码页。在历史上,IBM的个人计算机和微软公司的操作系统曾经是PC的标准配置。微软公司将IBM公司定义的代码页称作OEM代码页,在IBM公司的代码页基础上作了些增补后,作为自己的代码页,并冠以ANSI的字样。我们在“区域和语言选项”高级页面的代码页转换表中看到的包含ANSI字样的代码页都是微软自己定义的代码页。例如:
874 (ANSI/OEM - 泰文)
932 (ANSI/OEM - 日文 Shift-JIS)
936 (ANSI/OEM - 简体中文 GBK)
949 (ANSI/OEM - 韩文)
950 (ANSI/OEM - 繁体中文 Big5)
1250 (ANSI - 中欧)
1251 (ANSI - 西里尔文)
1252 (ANSI - 拉丁文 I)
1253 (ANSI - 希腊文)
1254 (ANSI - 土耳其文)
1255 (ANSI - 希伯来文)
1256 (ANSI - 阿拉伯文)
1257 (ANSI - 波罗的海文)
1258 (ANSI/OEM - 越南)
在UniToy中,我们可以按照代码页编码顺序查看这些代码页的字符和编码:
我们不能直接设置ANSI代码页,只能通过选择系统Locale,间接改变当前的ANSI代码页。微软定义的Locale只使用自己定义的代码页。所以,我们虽然可以通过“区域和语言选项”中的代码页转换表安装很多代码页,但只能将微软的代码页作为系统默认代码页。
在Windows 2000以后,Windows统一采用UTF-16作为内部字符编码。现在,安装一个代码页就是安装一张代码页转换表。通过代码页转换表,Windows既可以将代码页的编码转换到UTF-16,也可以将UTF-16转换到代码页的编码。代码页转换表的具体实现可以是一个以nls为后缀的数据文件,也可以是一个提供转换函数的动态链接库。有的代码页是不需要安装的。例如:Windows将UTF-7和UTF-8分别作为代码页65000和代码页65001。UTF-7、UTF-8和UTF-16都是基于Unicode的编码方案。它们之间可以通过简单的算法直接转换,不需要安装代码页转换表。
在安装过一个代码页后,Windows就知道怎样将该代码页的文本转换到Unicode文本,也知道怎样将Unicode文本转换成该代码页的文本。例如:UniToy有导入和导出功能。所谓导入功能就是将任一代码页的文本文件转换到Unicode文本;导出功能就是将Unicode文本转换到任一指定的代码页。这里所说的代码页就是指系统已安装的代码页:
其实,如果全世界人民在计算机刚发明时就统一采用Unicode作为字符编码,那么代码页就没有存在的必要了。可惜在Unicode被发明前,世界各国人民都发明并使用了各种字符编码方案。所以,Windows必须通过代码页支持已经被广泛使用的字符编码。从这种意义看,代码页主要是为了兼容现有的数据、程序和习惯而存在的