天天看點

《windows核心程式設計》筆記(二)

單位元組和雙位元組字元示例:

#include <string.h>

#include <locale.h>

#include <stdio.h>

#include <stdlib.h>

#include <mbstring.h>

int main()

{

   char* str1 = "Count.";

   wchar_t* wstr1 = L"Count.";

   char * mbstr1;

   char * locale_string;

   // strlen gives the length of single-byte character string

   printf("Length of '%s' : %d\n", str1, strlen(str1) );

   // wcslen gives the length of a wide character string

   wprintf(L"Length of '%s' : %d\n", wstr1, wcslen(wstr1) );

   // A multibyte string: [A] [B] [C] [katakana A] [D] [\0]

   // in Code Page 932. For this example to work correctly,

   // the Japanese language support must be enabled by the

   // operating system.

   mbstr1 = "ABC" "\x83\x40" "D";

   locale_string = setlocale(LC_CTYPE, "Japanese_Japan");

   if (locale_string == NULL)

   {

      printf("Japanese locale not enabled. Exiting.\n");

      exit(1);

   }

   else

      printf("Locale set to %s\n", locale_string);

   // _mbslen will recognize the Japanese multibyte character if the

   // current locale used by the operating system is Japanese

   printf("Length of '%s' : %d\n", mbstr1, _mbslen((const unsigned char*)mbstr1) );

   // _mbstrlen will recognize the Japanese multibyte character

   // since the CRT locale is set to Japanese even if the OS locale

   // isnot. 

   printf("Length of '%s' : %d\n", mbstr1, _mbstrlen(mbstr1) );

   printf("Bytes in '%s' : %d\n", mbstr1, strlen(mbstr1) );   

   system("pause");

}

2008060703.jpg

此外,windows還提供了一些函數來幫助我們對DBCS進行操作,比如CharPrev, CharNext, IsDBCSLeadByte等。

你應該知道的:

1) Windows 2000既支援Unicode,也支援ANSI,是以可以為任意一種開發應用程式。

2)Windows 98隻支援ANSI,隻能為ANSI開發應用程式。

3) Windows CE隻支援Unicode,隻能為Unicode開發應用程式。

4)當Microsoft公司将COM從1 6位Windows轉換成Win32時,公司作出了一個決定,即需要字元串的所有COM接口方法都隻能接受Unicode字元串。

要支援Unicode,隻需要定義兩個宏(UNICODE和_UNICODE),就可以修改然後重新編譯該源檔案。

C運作時庫也添加了對Unicode的支援,定義了wchat_t及相關的處理函數,如wcscat,wcschr,wcscpy,wcslen等。

但為了能建立ANSI/Unicode通用代碼,不應該直接調用str函數或wcs函數,而是應該使用一組宏,若定義了_UNICODE,就引用wsc這組函數,若沒有,則引用str這組函數。例如,_tcscpy這個宏,若定義了_UNICODE,就擴充為wcscpy,若沒有,則擴充為strcpy。

    TCHAR* szCh = _TEXT("error");

    if(szCh[0]==_TEXT('e'))

    {

        printf("ok");

    }

WHAR     Unicode字元

PWSTR    指向Unicode字元串的指針

PCWSTR   指向一個恒定的Unicode字元串的指針

這些資料類型是指Unicode字元和字元串。Windows頭檔案也定義了A N S I / Unicode通用資料類型PTSTR和PCTSTR。這些資料類型既可以指A N S I字元串,也可以指Unicode字元串,這取決于當編譯程式子產品時是否定義了Unicode宏。這裡的Unicode宏沒有前置的下劃線。_Unicode宏用于C運作期頭檔案,而Unicode宏則用于Windows頭檔案。當編譯源代碼子產品時,通常必須同時定義這兩個宏。

• 将文本串視為字元數組,而不是chars數組或位元組數組。

• 将通用資料類型(如TCHAR和PTSTR)用于文本字元和字元串。

• 将顯式資料類型(如BYTE和PBYTE)用于位元組、位元組指針和資料緩存。

• 将TEXT宏用于原義字元和字元串。

• 執行全局性替換(例如用PTSTR替換PSTR)。

• 修改字元串運算問題。例如函數通常希望你在字元中傳遞一個緩存的大小,而不是位元組。

這意味着你不應該傳遞sizeof (szBuffer ) ,而應該傳遞( sizeof (szBuffer ) / sizeof (TCHAR )。另外,如果需要為字元串配置設定一個記憶體塊,并且擁有該字元串中的字元數目,那麼請記住要按位元組來配置設定記憶體。這就是說,應該調用malloc(nCharacters *sizeof(TCHAR)), 而不是調用malloc( nChar)

Windows也提供了一組用于對Unicode字元串進行操作的函數

lstrcat 将一個字元串置于另一個字元串的結尾處

lstrcmp 對兩個字元串進行區分大小寫的比較

lstrcmpi 對兩個字元串進行不區分大小寫的比較

lstrcpy 将一個字元串拷貝到記憶體中的另一個位置

lstrlen 傳回字元串的長度(按字元數來計量)

C運作期函數strcmp、strcmp i、wcscmp和wcscmpi隻是對字元串中的代碼點的值進行比較,這就是說,這些函數将忽略實際字元的含義,隻是将第一個字元串中的每個字元的數值與第二個字元串中的字元的數值進行比較。而Windows函數lstrcmp和lstrcmpi是作為對Windows函數CompareString的調用來實作的。

 int CompareString(

  LCID Locale, 

  DWORD dwCmpFlags, 

  LPCTSTR lpString1, 

  int cchCount1, 

  LPCTSTR lpString2, 

  int cchCount2 

);

該函數對兩個Unicode字元串進行比較。CompareString的第一個參數用于設定語言I D(LCID),這是個32位值,用于辨別一種特定的語言。CompareString使用這個LCID來比較這兩個字元串,方法是對照一種特定的語言來檢視它們的字元的含義

LCID GetThreadLocale(void);

當lstrcmp函數系列中的任何一個函數調用CompareString時,該函數便将調用Windows的GetThreadLocale函數的結果作為第一個參數來傳遞:每次建立一個線程時,它就被賦予一種語言。函數将傳回該線程的目前語言設定。

#include <windows.h>

#include <tchar.h>     

#include <stdio.h>     

int CDECL MessageBoxPrintf (TCHAR * szCaption, TCHAR * szFormat, )

    TCHAR   szBuffer [1024] ;

    va_list pArgList ;

    // The va_start macro (defined in STDARG.H) is usually equivalent to:

    // pArgList = (char *) &szFormat + sizeof (szFormat) ;

    va_start (pArgList, szFormat) ;

    // The last argument to wvsprintf points to the arguments

    _vsntprintf (    szBuffer, sizeof (szBuffer) / sizeof (TCHAR), 

        szFormat, pArgList) ;

    // The va_end macro just zeroes out pArgList for no good reason

    va_end (pArgList) ;

    return MessageBox (NULL, szBuffer, szCaption, 0) ;

int WINAPI WinMain (    HINSTANCE hInstance, HINSTANCE hPrevInstance,

                    PSTR szCmdLine, int iCmdShow) 

    int cxScreen, cyScreen ;

    cxScreen = GetSystemMetrics (SM_CXSCREEN) ;

    cyScreen = GetSystemMetrics (SM_CYSCREEN) ;

    MessageBoxPrintf (    TEXT ("ScrnSize"), 

        TEXT ("The screen is %i pixels wide by %i pixels high."),

        cxScreen, cyScreen) ;

    return 0 ;

本文轉自Phinecos(洞庭散人)部落格園部落格,原文連結:http://www.cnblogs.com/phinecos/archive/2008/06/07/1215599.html,如需轉載請自行聯系原作者