/******************************************************************************
//DealUnicode.cpp
//使用Unicode字符集, 2009-11-26
//Unicode,
//DBCS 双字节字符集
//////////////////////////////////////////////////////////////////////////////////
//一般需同时包括
#define UNICODE //Windows C 宏
#define _UNICODE //ANSI C 宏
//Windows定义
WCHAR PWSTR PCWSTR LPCWSTR
TCHAR PTSTR PCTSTR LPCTSTR
//赋值方法
TCHAR *szStr = L"string"; //ANSI C
TCHAR *szStr = _TEXT("string"); //ANSI C 宏
TCHAR *szStr = TEXT("string"); //Windows C
//调用
if(szStr[0] == _TEXT('J'));
//////////////////////////////////////////////////////////////////////////////////
//在Windows API中,建议不再使用16位函数,如:WinExec, OpenFile, 而使用32位的
CreateProcess, CreateFile,因为16位版本不接受Unicode.
//建议使用操作系统函数,而不用CRT。特征是函数名大小写混编,StrCat, StrChr, StrCmp, StrCpy
//显式数据类型BYTE PBYTE用于字节,字节指针和数据缓存
//需要头文件:ShlWApi.h (库:Shlwapi.dll, shlwapi.lib)
//为字符串中传递缓存大小方法: sizeof(szBuffer)/sizeof(TCHAR);
为字符串分配内存:malloc(nChars*sizeof(TCHAR))
//函数:
PTSTR CharNext(PCTSTR pszCurrentChar); //下一个字符地址
PTSTR CharPrev(PCTSTR pszStart, //上一个字符地址
PCTSTR pszCurrentChar);
BOOL IsDBCSLeadByte(BYTE bTestChar); //如果该字节是DBCS字符的第一个字节,则TRUE
size_t _mbslen(const unsigned char *string); //字符串长
××××××××××××××××××××××××××××××××××××××
wchar_t * wcscat(wchar_t *, const wchar_t *);
wchar_t * wcschr(const wchar_t *, wchar_t);
int wcscmp(const wchar_t *, const wchar_t *);
wchar_t * wcscpy(wchar_t *, const wchar_t *);
size_t wcslen(const wchar_t *);
××××××××××××××××××××××××××××××××××××××
//Windows函数:
lstrcat, lstrcmp(区分大小写), lstrcmpi(不区分大小写), lstrcpy, lstrlen
PTSTR CharLower(PTSTR pszString); PTSTR CharUpper(PTSTR pszString); DWORD CharLowerBuff(LPTSTR lpsz, DWORD cch);
//如果单字符调用:TCHAR c = CharLower((PTSTR)szString[0]); //这时返回值是32位,低16为已转换的字符
//////////////////////////////////////////////////////////////////////////////////
//lstrcmp/i调用
int CompareString(
LCID lcid, //用于设定语言ID, 可用LCID GetThreadLocale();
DWORD fdwStyle, //比较的标识,忽略大小写,符合等,lstrcmp时=0,lstrcmpi时=NORM_IGNORECASE
PCTSTR pString1,
int cch1, //如=-1,则以0结尾的字符串
PCTSTR pString2,
int cch2 //同cch1
);
//////////////////////////////////////////////////////////////////////////////////
//sprintf, wsprintf使用注意区别:见Example1
//////////////////////////////////////////////////////////////////////////////////
//打开文本时注意区分是ANSI字符还是Unicode字符,可用:
DWORD IsTextUnicode(
CONST PVOID pvBuffer, //缓存地址
int cb, //字节数
PINT pResult //【in/out】
);
但在WIN98下,总是返回FALSE
//////////////////////////////////////////////////////////////////////////////////
//转换ANSI -> Unicode
int MultiByteToWideChar(
UINT uCodePage, //代码页号
DWORD dwFlags, //字符类型选择
PCTSTR pMultiByteStr,//ANSI字符串
int cchMultiByte, //字节数,如=-1,则此函数可以确定该字符串的长度
PWSTR pWideCharStr, //Unicode字符串缓存
int cchWideChar //该缓存的最大值,如=0,函数返回所需缓存的值
);
步骤:
1、用MultiByteToWideChar,pWideCharStr=NULL, cchWideChar=0,
2、分配内存,cchWideChar=1、的返回值,pWideCharStr=缓存地址
3、再用MultiByteToWideChar,( pWideCharStr=缓存地址,cchWideChar=1、的返回值)
4、使用pWideCharStr
5、释放内存
//////////////////////////////////////////////////////////////////////////////////
//转换 Unicode -> ANSI
int WideCharToMultiByte(
UINT uCodePage, //代码页号
DWORD dwFlags, //字符类型选择
PCWSTR pWideCharStr,//Unicode字符串缓存
int cchWideChar, //字节数,如=-1,则此函数可以确定该字符串的长度
PSTR pMultiByteStr, //ANSI字符串
int cchMultiByte, //该缓存的最大值,如=0,函数返回所需缓存的值
PCSTR pDefaultChar, //如果宽字符不能被转换,便用此字符替换;如=NULL(通常情况),则使用系统默认字符,通常为问号
PBOOL pfUseDefaultChar
);
*******************************************************************************/
void Example1(void)
{
char szA[100]; //An ANSI string buffer
WCHAR szW[100]; //A Unicode string buffer
//Normal sprintf: ANSI -> ANSI
sprintf(szA, "%s", "ANSI STR"); //第二个参数小写s
//Converts Unicode -> ANSI
sprintf(szA, "%S", L"Unicode str"); //第二个参数大写s
//Normal swprintf, UNICODE -> UNICODE
swprintf(szW, L"%s", L"Unicode str");//第二个参数小写s
//Converts ANSI -> UNICODE
swprintf(szw, L"%S", L"ANSI Str"); //第二个参数大写s
}
//////////////////////////////////////////////////////////////////////////////////////
//////如何让自定义的函数自动识别ANSI 和 Unicode///////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//为DLL的字符串处理函数分别定义ANSI 和 Unicode版本, eg:
//Unicode版本
BOOL StringReverseW(PWSTR pWideCharStr)
{
//Get a pointer to the last character in the string.
PWSTR pEndofStr = pWideCharSet + wcslen(pWideCharStr) - 1;
wchar_t cCharT;
//Repeat until we reach the center character in the string
while(pWideCharStr < pEndofStr){
//Save a character in a temporary variable
cCharT = * pWideCharStr;
//Put the last charater in the first character
*pWideCharStr = *pEndofStr;
//put the temporary character in the last character
*pEndofStr = cCharT;
//Move in one character from the left
pWideCharStr++;
//Move in one character from the right
pEndofStr--;
}
return (TRUE);
}
//ANSI版本
BOOL StringReverseA(PSTR pMultiByteStr)
{
PWSTR pWidCharStr;
int nLenofWCS;
BOOL fOK = FALSE;
//Calculate the number of characters needed to hold the wid-character version of the string
nLenofWCS = MultiByteToWideChar(CP_ACP, 0, pMultiByteStr, -1, NULL, 0);
//Allocate memory from the process's default heap to accommodate the size of the
//wide-character string.
//注意:MultiByteToWideChar返回的nLenofWCS是字符数(有多少字符),而非字节数
pWideCharStr = HeapAlloc(GetProcessHeap(), 0, nLenofWCS*sizeof(WCHAR));
if(pWideCharStr == NULL) return (fOK);
//Convert the multibyte string to a wide-character string
MultiByteToWideChar(CP_ACP, 0, pMultiByteStr, -1, pWideCharStr, nLenofWCS);
//Call the Wide-character version of this function to do the actual work.
fOK = StringReverseW(pWideCharStr);
if(fOK){
//Convert the wide-character string back to a multibyte string
WideCharToMultiByte(CP_ACP, 0, pWideCharStr, -1,
pMultiByteStr, strlen(pMultiByteStr), NULL, NULL);
}
//Free the memory containing the wide-character string
HeapFree(GetProcessHeap(), 0, pWideCharStr);
return (fOK);
}
/////////////////////////////////////////////////////////////////////////////
//然后在DLL的头文件中,做如下申明:
BOOL StringReverseW(PWSTR pWideCharStr);
BOOL StringReverseA(PSTR pMultiByteStr);
#ifdef UNICODE
#define StringReverse StringReverseW
#else
#define StringReverse StringReverseA
#endif //UNICODE
/////////////////////////////////////////////////////////////////////////////