马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 兰陵月 于 2018-10-26 13:40 编辑
2.3 宽字符和Windows
Windows NT从底层支持Unicode。这意味着Windows NT内部使用16位字符的字符串。因为时节上还有许多地方不使用16位字符串,所以Windows NT操作系统必须经常在内部转换字符串。在Windows NT上,既可执行为ASCII、Unicode单写的程序,也可执行为ASCII和Unicode混合编写的程序。其实这是通过Windows NT支持可以接受8位和16位的字符串的API函数调用来实现的。(我们将很快看到这些函数是如何工作。)
Windows 98对Unicode的支持比Windows NT少得多。只有几个Windows 98的API函数支持宽字符串。(在Microsoft Knowledge Base article Q125671中对这些函数有介绍;其中包括MessageBox。)如果要发行一个需要同时在Windows NT和Windows 98下都能执行的.EXE文件,那就不应该使用Unicode,否则就别期望它能在Windows 98下运行。特别需要指出的是,这个程序不应该调用Unicode版本的Windows API函数。但是,为了在将来需要发行支持Unicode的程序时,你能处于更有利的位置,你应该试着只拥有一个版本的原始码,它既可以被编译成ASCII,也可被编译成Unicode。这就是本书中所有程序的编写方式。
2.3.1 Windows头文件的类型
正如第1章所述,Windows程序包含着WINDOWS.H头文件。该头文件又包含着许多其他头文件,例如WINDEF.H,该文件又有许多在Windows中使用的基本数据类型的定义,同时它本身也包含WINNT.H。WINNT.H负责处理基本的Unicode支持功能。
上图:WINDOWS.H中包含着windef.h头文件
上图:WINDEF.H中包含着winnt.h头文件
上图:WINNT.H中包含着ctype.h头文件
WINNT.H在一开始就包含C的头文件CTYPE.H,而这是C的众多头文件之一,包含这wchar_t的定义。
上图:CTYPE.H中wchar_t的定义,无符号短整型。
WINNT.H定义了两个新的被称作CHAR和WCHAR的数据类型:
typedef char CHAR;
typedef wchar_t WCHAR;//wc
CHAR和WCHAR是写Windows程序时推荐使用的数据类型,它们分别用于定义8位或者16位的字符。WCHAR定义后面的注释wc,是建议使用匈牙利标记法来说明这是一个基于WCHAR数据类型的变量,即这是一个宽字符。
接下来,WINNT.H头文件定义了可用作8位字符串指针的6种数据类型和可用作const 8位字符串指针的4种数据类型。我在这里精选了头文件中的一些实际的数据类型语句来具体说明:
typedef CHAR *PCHAR, *LPCH, *PCH, *NPSTR, *LPSTR, *PSTR;
typedef CONST CHAR *LPCCH, *PCCH, *LPCSTR, *PCSTR;
前缀N和L代表着“近(near)”和“远(long)”,指的是16位Windows系统中的两种大小不同的指针。但在WIN32中near和long没有什么区别。
同样地,WINNT.H还定义了可作为16位字符串指针的6种数据类型和可作为const 16位字符串指针的4种数据类型。
typedef WCHAR *PWCHAR, *LPWCH, *PWCH, *NWPSTR, *LPWSTR, *PWSTR
typedef CONST WCHAR *LPCWCH, *PCWCH, *LPCWSTR, *PCWSTR
这样,我们就有了数据类型CHAR(8位的char)和WCHAR(16位的wchar_t),以及指向CHAR和WCHAR的各种指针。像在TCHAR.H中一样,WINNT.H将TCHAR定义为一个通用的字符类型。如果标识符UNICODE(没有下划线)被定义了,则TCHAR和指向TCHAR的指针就分别被定义为WCHAR和指向WCHAR的指针;如果标识符UNICODE没有被定义,则TCHAR和指向TCHAR的指针就分别被定义为char和指向char的指针:
上图表示WINNT.H中如果定义了标识符UNICODE的TCHAR类型
上图表示WINNT.H中如果未定义标识符UNICODE的TCHAR类型
如果TCHAR已经在某个头文件中被定义了,WINNT.H和WCHAR.H头文件都能防止TCHAR数据类型被重复定义。不管怎样,无论何时你在你的程序中使用其他头文件时,都应在所有其他头文件之前先包含WINDOWS.H头文件。
WINNT.H头文件还定义了一个宏,它将L添加到一个字符串的第一个引号前。如果UNICODE标识符被定义了,那么一个被称作__TEXT的宏则定义如下:
#define __TEXT(quote) L##quote
如果标识符UNICODE没有被定义,则如下定义__TEXT宏:
#define __TEXT(quote) quote
而不管怎样,TEXT宏可如下定义:
#define TEXT(quote) __TEXT(quote)
这像在TCHAR.H中定义_TEXT宏一样,只是不必操心下划线(_)。我将在本书中使用这个TEXT版本的宏。
这些定义让你在同一程序中能够混合使用ASCII和Unicode的字符串,或者是编写一个版本的源代码让它可被编译成ASCII或Unicode的程序。如果要明确定义8位字符变量和字符串,那就使用CHAR、PCHAR(或者其他的8位数据类型)以及带引号的字符串。如果为了明确定义16位字符变量和字符串,则使用WCHAR、PWCHAR,并将L添加到引号前面。至于如何选择8位还是16位变量以及字符串,则取决于UNICODE标识符是否已被定义以及是否已使用TCHAR、PTCHAR和TEXT宏。
|