windows核心程式設計--字符集

Mobidogs發表於2020-04-04
 字元unicode與windows

 
1 軟體的本地化要解決的真正問題,實際上就是如何來處理不同的字符集。以前我們習慣與用單位元組字符集來程式設計.
2 單字符集:將文字串作為一系列單位元組字元來進行編碼,並在結尾處放上一個零。(每個字元用一個位元組來表示)
3 雙位元組字符集(D B C S ):在雙位元組字符集中,字串中的每個字元可以包含一個位元組或包含兩個位元組。
4 unicode字符集:U n i c o d e 提供了一種簡單而又一致的表示字串的方法。U n i c o d e 字串中的所有字元都是1 6 位的(兩個位元組)。
5 當M i c r o s o f t 公司將C O M 從1 6 位Wi n d o w s 轉換成Wi n 3 2 時,公司作出了一個決定,即需要字串的所有C O M 介面方法都只能接受U n i c o d e 字串。
6 c執行期庫支援unicode,即使是windows98也支援.
7 Windows 2000 的N o t e p a d (記事本)應用程式允許你既能開啟U n i c o d e 檔案,也能開啟A N S I 檔案,並且可以建立這些檔案。
8 I s Te x t U n i c o d e 函式能夠幫助進行區分ANSIC字元和unicode:
DWORD IsTextUnicode(CONST PVOID pvBuffer, int cb,PINT pResult);

第一個引數p v B u ff e r 用於標識要測試的快取的地址。該資料是個無效指標,因為你不知道你擁有的是A N S I 字元陣列還是U n i c o d e 
字元陣列。

第二個引數c b 用於設定p v B u ff e r 指向的位元組數。同樣,由於你不知道快取中放的是什麼,因此c b 是個位元組數,而不是字元數。請注意,不必設定快取的整個長度。當然,I s Te x t U n i c o d e能夠測試的位元組越多,得到的結果越準確。

第三個引數p R e s u l t 是個整數的地址,必須在呼叫I s Te x t U n i c o d e 之前對它進行初始化。對該整數進行初始化後,就可以指明你要I s Te x t U n i c o d e 執行哪些測試。也可以為該引數傳遞N U L L ,在這種情況下,I s Te x t U n i c o d e 將執行它能夠進行的所有測試(詳細說明請參見Platform SDK 文件)。

9 對D B C S 字串進行操作的幫助函式

函式 描述
PTSTR CharNext(PCTSTR pszCurrentChar); 返回字串中的下一個字元的地址
PTSTR CharPrev (PCTSTR pszStart,PCTSTR p s z C u r r e n t C h a r); 返回字串中的上一個字元的地址
BOOL IsDBCSLeadByteTRUE(BYTE bTestChar); 如果該位元組是DBCS 字元的第一個位元組,則返回


10 “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 開發應用程式。

11 Wi n d o w s 標頭檔案定義de Uincode 資料型別

資料型別 說明
W C H A R U n i c o d e 字元
P W S T R 指向U n i c o d e 字串的指標
P C W S T R 指向一個恆定的U n i c o d e 字串的指標
使用例項如下:
#ifdef UNICODE
#define CreateWindowEx CreateWindowExW
#else
#define CreateWindowEx CreateWindowExA
#endif //!UNICODE
在Unicode與ANSI之間轉換字串

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 字串。該記憶體塊的大小由前面對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 字串佔用的記憶體塊。
函式Wi d e C h a r To M u l t i B y t e 將寬字串轉換成等價的多位元組字串,如下所示:


該函式與M u l t i B i 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 Wi d e C h a r S t r 引數用於設定要轉換的字串的記憶體地址,c c h Wi d e C h a r 引數用於指明該字串的長度(用字元數來計量)。如果你為c c h Wi d e C h a r 引數傳遞- 1 ,那麼該函式用於確定源字串的長度。

轉換產生的多位元組版本的字串被寫入由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引數中設定該快取的最大值(用位元組來計量)。如果傳遞0 作為Wi d e C h a r To M u l t i B y t e 函式的c c h M u l t i B y t e 引數,那麼該函式將返回目標快取需要的大小值。通常可以使用將多位元組字串轉換成寬位元組字串時介紹的一系列類似的事件,將寬位元組字串轉換成多位元組字串。

你會發現,Wi d e C h a r To M u l t i B y t e 函式接受的引數比M u l t i B y t e To Wi d e C h a r 函式要多2 個,即p D e f a u l t C h a r 和p f U s e d D e f a u l t C h a r 。只有當Wi d e C h a r To M u l t i B y t e 函式遇到一個寬位元組字元,而該字元在u C o d e P a g e 引數標識的內碼表中並沒有它的表示法時,Wi d e C h a r To M u l t i B y t e 函式才使用這兩個引數。如果寬位元組字元不能被轉換,該函式便使用p D e f a u l t C h a r 引數指向的字元。如果該引數是N U L L (這是大多數情況下的引數值),那麼該函式使用系統的預設字元。該預設字元通常是個問號。這對於檔名來說是危險的,因為問號是個萬用字元。

p f U s e d D e f a u l t C h a r 引數指向一個布林變數,如果寬字串中至少有一個字元不能轉換成等價多位元組字元,那麼函式就將該變數置為T R U E 。如果所有字元均被成功地轉換,那麼該函式就將該變數置為FA L S E 。當函式返回以便檢查寬位元組字串是否被成功地轉換後,可以測試該變數。同樣,通常為該測試傳遞N U L L 。

關於如何使用這些函式的詳細說明,請參見Platform SDK 文件。

如果使用這兩個函式,就可以很容易建立這些函式的U n i c o d e 版本和A N S I 版本。例如,你可能有一個動態連結庫,它包含一個函式,能夠轉換字串中的所有字元。可以像下面這樣編寫該函式的U n i c o d e 版本:


你可以編寫該函式的A N S I 版本以便該函式根本不執行轉換字串的實際操作。你也可以編寫該函式的A N S I 版本,以便該函式它將A N S I 字串轉換成U n i c o d e 字串,將U n i c o d e 字串傳遞給S t r i n g R e v e r s e W 函式,然後將轉換後的字串重新轉換成A N S I 字串。該函式類似下面的樣子:

 


最後,在用動態連結庫分配的標頭檔案中,可以像下面這樣建立這兩個函式的原型:

 


相關文章