《Windows核心编程》读书笔记(四)

第二章 Unicode

Windows 中的Unicode
    Windows头文件定义了几种关于Unicode的数据类型:
            WCHAR    Unicode字符
            PWSTR    指向Unicode字符串的指针
            PCWSTR   指向一个恒定的Unicode字符串的指针
同时Windows头文件也定业了ANSI/Unicode的通用数据类型,PTSTR和PCTSTR,这类数据指向那一种字符,取决于当编译程序模块时是否定义了UNICODE宏。这里这个宏UNICODE没有下划线前缀,带前缀的宏_UNICODE用于C运行期头文件。当编译源代码模块时,通常必须同时定义这两个宏。
       Windows中的函数CreatWindowsEx有两个版本,一个是接受Unicode字符串的,为CreatWindowsExW;一个接受ANSI字符串的,为CreatWindowsExA。我们在代码中,通常只包括了对CreatWindowsEx的调用,而不是直接调用这两者,因为在WinUser.h文件中,CreatWindowsEx实际上是定义为一个宏。故编译源代码模块时,调用的是哪CreatWindowsEx版本,取决于你是否已作了UNICODE的定义。
        若要创建供其它开发人员使用的DLL,DLL中最好提供两个输出函数,一个ANSI版本,一个Unicode版本,在ANSI版本中,只需要分配内存,执行必要的字符串转换,然后调用该函数的Unicode版本即可。
       Windows的一些老函数存在一个大问题,它们不接受Unicode字符串。这时候应该避免使用这些函数。所有新的和未过时的函数在Windows2000中都同时拥有ANSI和Unicode两个版本。

Windows字符串函数
     Windows提供了一组范围很广的字符串操作函数,它们是操作系统的一个组成部分,常常被大型应用程序所使用。由于这些函数使用得比较多,故在你的应用程序运行时,它们可能被装进RAM,所以调用它们而不是使用C运行期库,会有助于稍稍提高你的运行性能。要使用经典的操作系统函数样式中的操作字符串的函数,必须加上ShlWApi.h头文件。这些字符串函数,既有ANSI版,也有Unicode版本,因此,当创建应用程序时,如果定义了Unicode,那么它们会自动扩展为宽字符版本。

成为符合ANSI和Unicode的应用程序
    要使你的应用程序符合Unicode,应该遵循下面一些基本原则:
        1.将文本串视为字符数组,而不是chars数组或字节数组。
        2.将通用数据类型(如TCHAR和PTSTR)用于文本字符和字符串。
        3.将显式数据类型(如BYTE和PBYTE)用于字节、字节指针和数据缓存。
        4.将TEXT宏用于原义字符和字符串。
        5.执行全局性替换(例如用PTSTR替换PSTR)。
        6.修改字符串运算问题。例如函数通常希望你在字符中传递一个缓存的大小,而不是字节。这意味着你不应该传递sizeof(szBuffer) ,而应该传递(sizeof(szBuffer)/sizeof(TCHAR )。另外,如果需要为字符串分配一个内存块,并且拥有该字符串中的字符数目,那么请记住要按字节来分配内存。这就是说,应该调用malloc(nCharacters *sizeof(TCHAR)), 而不是调用
malloc(nCharacters)。在上面所说的所有原则中,这是最难记住的一条原则,如果操作错误,编译器将不发出任何警告。
     Windwos提供了如下一组对Unicode字符串进行操作的函数:
           lstrcat    将一个字符串置于另一个字符串的结尾处
           lstrcmp    对两个字符串进行区分大小写的比较
           lstrcmpi   对两个字符串进行不区分大小写的比较
           lstrcpy    将一个字符串拷贝到内存中的另外一个位置
           lstrlen    返回字符串的长度
这些函数都是作为宏来实现的,即是说它们可作为Unicode/ANSI的通用版本,会根据是否定义了UNICODE而自动扩展。
    Windows提供了两个函数,以便转换Unicode字符串的大小写字母:
          PTSTR CharLower(PTSTR pszString);
          PTSTR CharUpper(PTSTR pszString);
既可以转换单个字符,也可以转换以0结尾的整个字符串。若要转换整个字符串,只需要传递字符串的地址即可。若要转换单个字符,则必须像下面这样传递各个字符:
          TCHAR cLowerCaseChar = CharLower(PTSTR) szString[0];
将单个字符转换成一个PTSTR,便可调用该函数,将一个值传递给它,在这个值中,较低的16位包含了该字符,较高的16位包含0。当该函数看到较高位是0时,该函数就知道你想要转换单个字符,而不是整个字符串。返回的值是个32位值,较低的16位中是已经转换的字符。
    当资源编译器对你的所有资源进行编译时,输出文件是资源的二进制文件。资源(字符串表、对话框模板和菜单等)中的字符串值总是写Unicode字符串。
       Windows用IsTextUnicode函数来区分所打开文本是ANSI字符还Unicode字符。
          DWORD IsTextUnicode(CONST PVOID pvBuffer , int cb , PINT pResult);
文本文件存在的问题是,它们的内容没有严格和明确的规则,因此很难确定该文件是包含ANSI字符还是Unicode字符。IsTextUnicode使用一系列统计方法和定性方法,以便猜测缓存的内容。由于这不是一种确切的科学方法,因此IsTextUnicode有可能返回不正确的结果。
        2004年11月11日

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值