WINDOWS核心編程–第二章UNICODE

來源:互聯網
上載者:User
下面讓我們進一步明確一下“M i c r o s o f t公司對U n i c o d e支援的情況”:
• Windows 2000既支援U n i c o d e,也支援A N S I,因此可以為任意一種開發應用程式。
• Windows 98隻支援A N S I,只能為A N S I開發應用程式。
• Windows CE只支援U n i c o d e,只能為U n i c o d e開發應用程式。

如何編寫U n i c o d e原始碼
M i c r o s o f t公司為U n i c o d e設計了Windows API,這樣,可以盡量減少對你的代碼的影響。實
際上,你可以編寫單個原始碼檔案,以便使用或者不使用U n i c o d e來對它進行編譯。只需要定
義兩個宏(U N I C O D E和_ U N I C O D E),就可以修改然後重新編譯該源檔案。

為了利用U n i c o d e字串,定義了一些資料類型。標準的C標頭檔S t r i n g . h已經作了修改,
以便定義一個名字為w c h a r _ t的資料類型,它是一個U n i c o d e字元的資料類型:
typedef unsigned char  wchar_t;
標準的C運行期字串函數,如
s t r c p y、s t r c h r和s t r c a t等,只能對A N S I字串進行操作,不能正確地處理U n i c o d e字串。因此,
ANSI C也擁有一組補充函數。,所有的U n i c o d e函數均以w c s開頭,w c s是寬字元串的英文縮寫。若要調用U n i c o d e函數,只需用首碼w c s來取代A N S I字串函數的首碼s t r即可

對於包含了對s t r函數或w c s函數進行顯式調用的代碼來說,無法非常容易地同時為A N S I和
U n i c o d e對這些代碼進行編譯。本章前面說過,可以建立同時為A N S I和U n i c o d e進行編譯的單
個原始碼檔案。若要建立雙重功能,必須包含T C h a r. h檔案,而不是包含S t r i n g . h檔案。

T C h a r. h檔案的唯一作用是協助建立A N S I / U n i c o d e通用原始碼檔案。它包含你應該用在源
代碼中的一組宏,而不應該直接調用s t r函數或者w c s函數。如果在編譯原始碼檔案時定義了
_ U N I C O D E,這些宏就會引用w c s這組函數。如果沒有定義_ U N I C O D E,那麼這些宏將引用s t r
這組宏。
例如,在T C h a r. h中有一個宏稱為_ t c s c p y。如果在包含該標頭檔時沒有定義_ U N I C O D E ,那
麼_ t c s c p y就會擴充為A N S I的s t r c p y函數。但是如果定義了_UNICODE, _tcscpy將擴充為U n i c o d e
的w c s c p y函數。擁有字串參數的所有C運行期函數都在T C h a r. h檔案中定義了一個通用宏。如
果使用通用宏,而不是A N S I / U n i c o d e的特定函數名,就能夠順利地建立可以為A N S I或U n i c o d e
進行編譯的原始碼。

按照預設設定, M i c r o s o f t公司的C + +編譯器能夠編譯所有的字串,就像它們是A N S I字串,而不是U n i c o d e字串。因此,如果沒有定義_ U N I C O D E,該編譯器將能正確地編譯這一行代碼:TCHAR *szError="Error"。但是,如果定義了_ U N I C O D E,就會產生一個錯誤。若要產生一個U n i c o d e字串而不是A N S I字串,必須將該程式碼改寫為下面的樣子:TCHAR *szError=L"Error";字串(literal string)前面的大寫字母L,用於告訴編譯器該字串應該作為U n i c o d e字串來編譯。當編譯器將字串置於程式的資料部分中時,它在每個字元之間分散插入零位元組。這種變更帶來的問題是,現在只有當定義了_ U N I C O D E時,程式才能成功地進行編譯。我們需要另一個宏,以便有選擇地在字串的前面加上大寫字母L。這項工作由_ T E X T宏來完成,_ T E X T宏也在T C h a r. h檔案中做了定義。使用該宏_TEXT("Error"),可以改寫上面這行代碼,這樣,無論是否定義了_ U N I C O D E宏,它都能夠正確地進行編譯.

Wi n d o w s定義的U n i c o d e資料類型
Wi n d o w s標頭檔也定義了A N S I / U n i c o d e通用資料類型P T S T R和P C T S T R。這些資料類型既可以指A N S I字串,也可以指U n i c o d e字串,這取決於當編譯器模組時是否定義了U N I C O D E宏。請注意,這裡的U N I C O D E宏沒有前置的底線。_ U N I C O D E宏用於C運行期標頭檔,而U N I C O D E宏則用於Wi n d o w s標頭檔。當編譯原始碼模組時,通常必須同時定義這兩個宏。

C r e a t e Wi n d o w E x W是接受U n i c o d e字串的函數版本。函數名結尾處的大寫字母W是英文w i d e
(寬)的縮寫。每個U n i c o d e字元的長度是1 6位,因此,它們常常稱為寬字元。C r e a t e Wi n d o w E x A
的結尾處的大寫字母A表示該函數可以接受A N S I字串。但是,在我們的代碼中,通常只包含了對C r e a t e Wi n d o w E x的調用,而不是直接調用C r e a t e Wi n d o w E x W或者C r e a t e Wi n d o w E x A。在Wi n U s e r. h檔案中,C r e a t e Wi n d o w E x實際上是定義為一個宏.

建議最好使用作業系統函數,而不要使用C運行期字串函數。這將有助於稍稍提高你的應用程式的運行效能,因為作業系統字串函數常常被大型應用程式比如作業系統的外殼進程E x p l o r e r. e x e所使用。由於這些函數使用得很多,因此,在你的應用程式運行時,它們可能已經被裝入R A M。在經典的作業系統函數樣式中,作業系統字串函數名既包含大寫字母,也包含小寫字母,它的形式類似這個樣子: S t r C a t、S t r C h r、S t r C m p和S t r C p y等。若要使用這些函數,必須加上S h l WA p i . h標頭檔。另外,如前所述,這些字串函數既有A N S I版本,也有U n i c o d e版本,例如S t r C a t A和S t r C a t W。由於這些函數屬於作業系統函數,因此,當建立應用程式時,如果定義了U N I C O D E(不帶前置底線),那麼它們的符號將擴充為寬字元版本。

成為符合A N S I和U n i c o d e的應用程式

下面是應該遵循的一些基本原則:
• 將文本串視為字元數組,而不是c h a r s數組或位元組數組。
• 將通用資料類型(如T C H A R和P T S T R)用於文本字元和字串。
• 將顯式資料類型(如B Y T E和P B Y T E)用於位元組、位元組指標和資料緩衝。
• 將T E X T宏用於原義字元和字串。
• 執行全域性替換(例如用P T S T R替換P S T R)。
• 修改字串運算問題。例如函數通常希望你在字元中傳遞一個緩衝的大小,而不是位元組。
這意味著你不應該傳遞s i z e o f ( s z B u ff e r ) ,而應該傳遞( s i z e o f ( s z B u ff e r ) / s i z e o f ( T C H A R )。另外,如果需要為字串分配一個記憶體塊,並且擁有該字串中的字元數目,那麼請記住要按位元組來
分配記憶體。這就是說,應該調用malloc(nCharacters *sizeof(TCHAR)), 而不是調用m a l l o c
( n C h a r a c t e r s )。在上面所說的所有原則中,這是最難記住的一條原則,如果操作錯誤,編譯器
將不發出任何警告。

資源
當資源編譯器對你的所有資源進行編譯時間,輸出檔案是資源的二進位檔案。資源(字串
表、對話方塊模板和菜單等)中的字串值總是寫作U n i c o d e字串。在Windows 98和Wi n d o w s
2 0 0 0下,如果應用程式沒有定義U N I C O D E宏,那麼系統就會進行內部轉換。
例如,如果在編譯原始碼模組時沒有定義U N I C O D E,調用L o a d S t r i n g實際上就是調用
L o a d S t r i n g A函數。這時L o a d S t r i n g A就從你的資源中讀取字串,並將該字串轉換成A N S I字
符串。A N S I形式的字串將從該函數返回給你的應用程式。

在U n i c o d e與A N S I之間轉換字串
Wi n d o w s函數M u l t i B y t e To Wi d e C h a r用於將多位元組字串轉換成寬字元串。下面顯示了
M u l t i B y t e To Wi d e C h a r函數。
u C o d e P a g e參數用於標識一個與多位元組字串相關的字碼頁號。d w F l a g s參數用於設定另一
個控制項,它可以用重音符號之類的區分標記來影響字元。這些標誌通常並不使用,在d w F l a g s
參數中傳遞0。p M u l t i B y t e S t r參數用於設定要轉換的字串, c c h M u l t i B y t e參數用於指明該字元
串的長度(按位元組計算)。如果為c c h M u l t i B y t e參數傳遞- 1,那麼該函數用於確定源字串的長
度。
轉換後產生的U n i c o d e版本字串將被寫入記憶體中的緩衝,其地址由p Wi d e C h a r S t r參數指
定。必須在c c h Wi d e C h a r參數中設定該緩衝的最大值(以字元為計量單位)。如果調用
M u l t i B y t e To Wi d e C h a r,給c c h Wi d e C h a r參數傳遞0,那麼該參數將不執行字串的轉換,而是
返回為使轉換取得成功所需要的緩衝的值。一般來說,可以通過下列步驟將多位元組字串轉換
成U n i c o d e等價字串:
1) 調用M u l t i B y t e To Wi d e C h a r函數,為p Wi d e C h a r S t r參數傳遞N U L L,為c c h Wi d e C h a r參數
傳遞0。
2) 分配足夠的記憶體塊,用於存放轉換後的U n i c o d e字串。該記憶體塊的大小由前面對
第2章Unicode計計23
下載
M u l t B y t e To Wi d e C h a r的調用返回。
3) 再次調用M u l t i B y t e To Wi d e C h a r,這次將緩衝的地址作為p Wi d e C h a r S t r參數來傳遞,並
傳遞第一次調用M u l t i B y t e To Wi d e C h a r時返回的緩衝大小,作為c c h Wi d e c h a r參數。
4. 使用轉換後的字串。
5) 釋放U n i c o d e字串佔用的記憶體塊

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.