从char/wchar_t到TCHAR(1) 转http://blog.pfan.cn/xman/34551.html

一.ANSIUNICODE

   1.为什么要使用Unicode
  
1 可以很容易地在不同语言之间进行数据交换。
  
2 使你能够分配支持所有语言的单个二进制.exe文件或DLL文件。
 
3 提高应用程序的运行效率。
   Windows 2000
是使用Unicode从头进行开发的,如果调用任何一个Windows函数并给它传递一个ANSI字符串,那幺系统首先要将字符串转换成Unicode,然后将Unicode字符串传递给操作系统。如果希望函数返回ANSI字符串,系统就会首先将Unicode字符串转换成ANSI字符串,然后将结果返回给你的应用程序。进行这些字符串的转换需要占用系统的时间和内存。通过从头开始用Unicode来开发应用程序,就能够使你的应用程序更加有效地运行。
Windows CE
本身就是使用Unicode的一种操作系统,完全不支持ANSI Windows函数
Windows 98
只支持ANSI,只能为ANSI开发应用程序。
Microsoft
公司将COM16Windows转换成Win32时,公司定需要字符串的所有COM接口方法都只能接受Unicode字符串。

   2ANSI字符和Unicode字符
   ANSI字符类型为CHAR指向字符串的指针PSTR(LPSTR),指向一个常数字符串的指针PCSTR(LPCSTR)

对应的Windows定义的Unicode字符类型为WCHARtypedef WCHAR wchar_t ,指向Unicode字符串的指针PWSTR ,指向一个常数Unicode字符串的指针PCWSTR

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

  3ANSI字符和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/wcschrstrcmp/wcscmpstrlen/wcslen etc.
ANSI 操作函数以str开头 strcpy
Unicode
操作函数以wcs开头 wcscpy
MBCS
操作函数以_mbs开头 _mbscpy
ANSI/Unicode
操作函数以_tcs开头 _tcscpyC运行期库)
ANSI/Unicode
操作函数以lstr开头 lstrcpyWindows函数)
   
所有新的和未过时的函数在Windows2000中都同时拥有ANSIUnicode两个版本。ANSI版本函数结尾以A表示;Unicode版本函数结尾以W表示。

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

Neutral ANSI/UNICODE types

1.通用字符型TCHAR

TCHAR  

ifdef UNICODE  it   is   wchar_tWCHARfor Unicode platforms;

else it   is   char for   ANSI   and  DBCS   platforms.

2.通用字符串指针LPTSTR

LPTSTR 

ifdef UNICODE it is LPWSTR*wchar_tfor  Unicode platforms;

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

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

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>UnicodeANSI字符串的转换:Windows函数MultiByteToWideChar函数用于将多字节字符串转换成宽字符串,函数WideCharToMultiByte将宽字符串转换成等价的多字节字符串。

三.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.dllUNCURL地址动态链接库文件,用于注册键值和色彩设置。因为操作系统字符串函数常常被大型应用程序比如操作系统的外壳进程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

原文地址:https://www.cnblogs.com/zhxiaomiao/p/1571029.html