从char/wchar_t到TCHAR(1)

一. ANSI UNICODE

 

1 .为什么要使用 Unicode  

1 可以很容易地在不同语言之间进行数据交换。

2 使你能够分配支持所有语言的单个二进制 .exe 文件或 DLL 文件。

3 提高应用程序的运行效率。  

Windows 2000 是使用 Unicode 从头进行开发的,如果调用任何一个 Windows 函数并给它传递一个 ANSI 字符串,那么系统首先要将字符串转换成 Unicode ,然后将 Unicode 字符串传递给操作系统。如果希望函数返回 ANSI 字符串,系统就会首先将 Unicode 字符串转换成 ANSI 字符串,然后将结果返回给你的应用程序。进行这些字符串的转换需要占用系统的时间和内存。通过从头开始用 Unicode 来开发应用程序,就能够使你的应用程序更加有效地运行。

Windows 98 只支持 ANSI ,只能为开发 ANSI 应用程序。 Windows CE 就是使用 Unicode 的操作系统,完全不支持 ANSI 版函数。

Microsoft COM Win16 转换成 Win32 时,所有 COM 接口方法都只能接受 Unicode 字符串。

2 ANSI 字符和 Unicode 字符

ANSI 字符类型为 CHAR 指向字符串的指针 PSTR(LPSTR) 指向一个常数字符串的指针 PCSTR(LPCSTR) ;对应的 Windows 定义的 Unicode 字符类型为 WCHAR typedef WCHAR wchar_t ,指向 Unicode 字符串的指针 PWSTR ,指向一个常数 Unicode 字符串的指针 PCWSTR

ANSI “ANSI” 

Unicode L “UNICODE”

ANSI/Unicode T (“string”) _TEXT (“string”)

3 ANSI 字符和 Unicode 字符串的操作

双字节(DBCS) 字符集中,字符串的每个字符可以包含一个或两个字节。 如果只是调用strlen() 函数,那么你就无法知道字符串到底有多少个字符,它只能告诉你到达结尾的0 之前有多少个字节。

标准c 中的strcpy,strchr,strcat 等只能用于ANSI 字符串,不能正确处理Unicode 字符串,因此也提供了一组补充函数,功能等价,但用于Unicode 码。我们来看看string .h 字符串头文件中是怎样处理char*wchar_t* 两个字符串版本的:

// /Microsoft Visual Studio 8/VC/include/string.h

char *strcat( char *, const char *);

wchar_t *wcschr(wchat_t*, const wchar_t *);

类似的还有strchr /wcschr strcmp /wcscmp strlen /wcslen etc. ANSI 操作函数以 str 开头 strcpy Unicode 操作函数以 wcs 开头 wcscpy

MBCS 操作函数以 _mbs 开头 _mbscpy

ANSI/Unicode 操作函数以 _tcs 开头 _tcscpy C 运行期库)

ANSI/Unicode 操作函数以 lstr 开头 lstrcpy Windows API

所有新的和未过时的函数在 Windows2000 中都同时拥有 ANSI Unicode 两个版本。 ANSI 版本函数结尾以 A 表示; Unicode 版本函数结尾以 W 表示。

二.ANSI/UNICODE 通用字符/ 字符串类型 TCHAR/LPTSTR/LPCTSTR

Neutral ANSI/UNICODE types

1 .通用字符型TCHAR

ifdef UNICODE   it is wchar_t WCHAR for Unicode platforms;

else it is char for ANSI and DBCS platforms.

2 .通用字符串指针LPTSTR

ifdef UNICODE it is LPWSTR *wchar_t for  Unicode platforms;

else it is LPSTR (*char) for ANSI and DBCS platforms.

3 .通用通用常数字符串指针LPCTSTR

ifdef   UNICODE it is LPCWSTR(*const wchar_t) for Unicode platforms;

else it is LPCSTR (*const char) for ANSI and DBCS platforms.

 

typedef LPWSTR LP ;

#define __TEXT (quote) L # #quote  // r_winnt

<1> _UNICODE 宏用于C 运行期头文件,UNICODE 宏则用于Windows 头文件, 当编译代码模块时,通常必须同时定义这两个宏。

<2> 如果定义了_UNICODE ,若要生成一个Unicode 字符串, 字符串前要加L 宏,用于告诉编译器该字符串应该作为Unicode 字符串来编译处理。但是这样又有个问题就是如果没有定义_UNICODE 则编译出错。为了解决这个问题我们必须用到_TEXT 宏,这个宏也在TChar.h 中做了定义。使用该宏后,无论源文件有没有定义_UNICODE 都不会出现编译错误。

<3> Unicode ANSI 字符串的转换: Windows 函数MultiByteToWideChar / mbstowcs 函数用于将多字节字符串转换成宽字符串, 函数WideCharToMultiByte /wcstombs 将宽字符串转换成等价的多字节字符串。

三.ANSI/UNICODE 字符串通用函数 lstrcmp/lstrcpy/lstrcat/lstrlen

// /Microsoft Visual Studio 8/VC/PlatformSDK/Include/Winbase.h --

已经包含在windows.h 中。

lstrcmp (lstrcmpi)

WINBASEAPI

int

WINAPI

lstrcmpA(

    __in LPCSTR lpString1,

    __in LPCSTR lpString2

    );

WINBASEAPI

int

WINAPI

lstrcmpW(

    __in LPCWSTR lpString1,

    __in LPCWSTR lpString2

    );

#ifdef UNICODE

#define lstrcmp   lstrcmpW

#else

#define lstrcmp   lstrcmpA

#endif // !UNICODE

lstrcpy

WINBASEAPI

__out

LPSTR

WINAPI

lstrcpyA(

    __out LPSTR lpString1,

    __in  LPCSTR lpString2

    );

WINBASEAPI

__out

LPWSTR

WINAPI

lstrcpyW(

    __out LPWSTR lpString1,

    __in  LPCWSTR lpString2

    );

#ifdef UNICODE

#define lstrcpy   lstrcpyW

#else

#define lstrcpy   lstrcpyA

#endif // !UNICODE

另外还有lstrcat(W/A)lstrlen(W/A) ,这里未列出其函数定义。

四.使用 shlwapi 头文件中定义的函数 StrCat/StrCmp/StrCpy

shlwapi.dll UNC URL 地址动态链接库文件,用于注册键值和色彩设置。因为操作系统字符串函数常常被大型应用程序比如操作系统的外壳进程 Explorer.exe 所使用。由于这些函数使用得很多,因此,在应用程序运行时,它们可能已经被装入 RAM 。这将有助于稍稍提高应用程序的运行性能。

// …/Microsoft Visual Studio 8/VC/PlatformSDK/Include/shlwapi.h

 

注意:使用StrCatStrCmpStrCpy etc 时要#include   "shlwapi.h"

LWSTDAPI_(LPWSTR)   StrCatW(LPWSTR psz1, LPCWSTR psz2);

LWSTDAPI_(int)      StrCmpW(LPCWSTR psz1, LPCWSTR psz2);

LWSTDAPI_(LPWSTR)   StrCpyW(LPWSTR psz1, LPCWSTR psz2);

#ifdef UNICODE

#define StrCat                   StrCatW

#define StrCmp                  StrCmpW

#define StrCpy                  StrCpyW

#else

#define StrCat                  lstrcatA

#define StrCmp                   lstrcmpA

#define StrCpy                  lstrcpyA

etc

参考:

VC 中的 __T 宏》 http://www.diybl.com/course/3_program/vc/vc_js/2008830/138819.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值