使用Unicode

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

/////////////////////////////////////////////////////////////////////////////

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章