/******************************************************************************
//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
/////////////////////////////////////////////////////////////////////////////