1. 程式人生 > >Windows程式設計中UNICODE和_UNICODE定義問題

Windows程式設計中UNICODE和_UNICODE定義問題

我初學Windows SDK程式設計時也碰到過這個問題,相信很多初學Windows程式設計的人也都碰到過,後來慢慢搞明白些了,但有時別人問到自己也說不太 清楚。今天藉此機會,我也好好整理一下自已的思路,用下面這篇文章詳細點地解釋下這個問題,希望能幫助到有此疑問的朋友。

UNICODE和_UNICODE並不是在標頭檔案中“定義”的,而是程式設計師通過以下方法之一定義的:
1、用程式碼定義的,就像你上面的一樣;
2、編譯選項中指定。比如在VC中是:

Project->Settings->C/C++->Category->Preprocessor->Preprocessor definitions

這裡是預處理指令,還有一些其它常見的常量如:WIN32,_DEBUG,NDEBUG,_WINDOWS等。

所以你在標頭檔案中找不到它的定義(注意是定義,不是使用,使用的地方則很多)。

但這兩個符號對Windows程式卻是有特定含義的,也就是說你不能將UNICODE定義為:Unicode,unicode,UseUnicode...否則毫無作用。因為在很多的標頭檔案中,這兩個符號用來判斷:

1、用那一種編碼方式,即Unicode和單位元組;
2、一些Windows中特定的型別的含義;
3、根據即Unicode和單位元組編碼的不同而選擇不同組的字元處理函式。

例如_UNICODE的例子你可以在TCHAR.H中找到,它用來解析TCHAR等型別是寬字元還是單位元組字元,以及一些字串巨集的處理結果是寬字元還是單位元組,比如:

#ifdef  _UNICODE                   
typedef wchar_t TCHAR ;
#else 
typedef char TCHAR ;
#endif

還有類似的方式定義的巨集:
_TEXT ("Hello!") , _T ("Hello!") , TEXT ("Hello!") , L ("Hello!") 

上面的巨集全是一個意思:如果是UNICODE,則算是是寬字元;否則處理為傳統單位元組ASCII字元。

UNICODE在很多標頭檔案中和_UNICODE一樣用來解析TCHAR等型別是寬字元還是單位元組字元,例如WINNT.H中:

#ifdef  UNICODE                   
typedef WCHAR TCHAR, * PTCHAR ;
typedef LPWSTR LPTCH, PTCH, PTSTR, LPTSTR ;
typedef LPCWSTR LPCTSTR ;
#else 
typedef char TCHAR, * PTCHAR ;
typedef LPSTR LPTCH, PTCH, PTSTR, LPTSTR ;
typedef LPCSTR LPCTSTR ;
#endif

同時用來選擇字元處理函式,例如WINUSER.H中:

#ifdef UNICODE
#define MessageBox  MessageBoxW
#else
#define MessageBox  MessageBoxA
#endif 

這 樣,我們只用一種型別(比如TCHAR)和一組函式(比如MessageBox)就方便地可以處理兩種編碼的程式,而不用去條件判斷應該用char還是 wchar_t,應該用MessageBoxA還是MessageBoxW。這些細節Windows.h等標頭檔案中已經為我們考慮了,我們要做的只是在需 要用Unicode時定義兩個符號。

而另一方面,Windows.h經過輾轉#include,又將WINNT.H、WINUSER.H 等很多標頭檔案包含了進去,很多地方還有重複交叉的(當然用條件編譯過濾過了),所以兩個符號(UNICODE、_UNICODE)都要定義,否則像上面少 定義了一個的話,結果將很難預料。