Windows中的Unicode和ANSI 函数

        自Windows NT起,Windows的所有版本都完全用Unicode来构建。也就是说,所有核心函数(创建窗口、显示文本、进行字符串处理等等)都需要Unicode字符串。调用一个Windows函数时,如果向它传入一个ANSI字符串(由单字节字符组成的一个字符串),函数首先会把字符串转换为Unicode,再把结果传给操作系统。如果希望函数返回ANSI字符串,那么操作系统会先把Unicode字符串转换为ANSI字符串,再把结果返回给你的应用程序。所有这些转换都是悄悄地进行的。当然,为了执行这些字符串转换,系统会产生时间和内存上的开销。

        如果一个Windows函数需要获取一个字符串作为参数,则该函数通常有两个版本。例如,一个CreateWindowEx接受Unicode字符串,另一个CreateWindowEx则接受ANSI字符串。这没错,但两个函数的原型实际是这样的:

       HWND WINAPI CreateWindowExW(
                                                                 DWORD dwExStyle,
                                                                 PCWSTR pClassName,  // A Unicode string 
                                                                 PCWSTR pWindowName, // A Unicode string
                                                                 DWORD dwStyle,
                                                                 int X, 
                                                                 int Y,
                                                                 int nWidth,
                                                                 int nHeight,
                                                                 HWND hWndParent,
                                                                 HMENU hMenu,
                                                                 HINSTANCE hInstance,
                                                                 PVOID pParam);  
        HWND WINAPI CreateWindowExA( 
                                                                 DWORD dwExStyle,
                                                                 PCSTR pClassName,  // An ANSI string
                                                                 PCSTR pWindowName, // An ANSI string
                                                                 DWORD dwStyle,
                                                                 int X, 
                                                                 int Y,
                                                                 int nWidth,
                                                                 int nHeight,
                                                                 HWND hWndParent,
                                                                 HMENU hMenu, 
                                                                 HINSTANCE hInstance, 
                                                                 PVOID pParam);  

CreateWindowExW这个版本接受Unicode字符串。函数名末尾的大写字母W代表wide。Unicode字符都是16位宽,所以它们常常被称作宽(wide)字符。CreateWindowExA  末尾的大写字母A表明该函数接受ANSI字符串。

但在平时,我们只是在自己的代码中调用CreateWiCreateWindowExW或CreateWindowExA。在WinU宏,它的定义如下: 
       #ifdef UNICODE
       #define CreateWindowEx CreateWindowExW 
       #else
       #define CreateWindowEx CreateWindowExA
       #endif

编译源代码模块时,是否定义UNICODE决定了要调用哪一个版本的CreateWindowEx。用Visual Studio创建一个新项目的时候,它默认会定义UNICODE。所以,在默认情况下,对CreateWindowEx的任何调用都会扩展宏来调用CreateWindowExW——即Unicode版本的CreateWindowEx。

 

C运行库中的Unicode函数和ANSI函数

       和Windows函数一样,C运行库提供了一系列函数来处理ANSI字符和字符串,并提供了另一系列函数来处理Unicode字符与字符串。然而,与Windows不同的是, ANSI版本的函数是“自力更生”的:它们不会把字符串转换为Unicode形式,再从内部调用函数的Unicode版本。当 然,Unicode版本的函数也是“自力更生”的,它们不会在内部调用ANSI版本。
 
在C运行库中,能返回ANSI字符串长度的一个函数的例子是strlen。与之对应的是wcslen,这个C运行库函数能返回Unicode字符串的长度。
 
这两个函数的原型都在String.h中。为了使你的源代码针对ANSI或Unicode都能编译,那么还必须包含TChar.h,该文件定义了以下宏:
 
#ifdef _UNICODE
#define _tcslen wcslen
#else
#define _tcslen strlen
#endif   

现在,在你的代码中应该调用_tcslen。如果已经定义了_UNICODE,它会扩展为wcslen;否则,它会扩展为strlen。默认情况下,在Visual Studio中新建一个C++项目时,已经定义了_UNICODE(就像已经定义了UNICODE一样)。针对不属于C++标准一部分的标识符,C运行库始终为其附加下划线前缀。但是,Windows团队没有这样做。所以,在你的应用程序中,应确保要么同时定义了UNICODE和_UNICODE,要么一个都不要定义。附录A将详细描述CmnHdr.h;本书所有示例代码都将用这个头文件来避免这种问题。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值