日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Unicode與Windows編程(3) | 夢之城堡

UnicodeWindows編程(3)

2.8 如何編寫UNICODE源代碼

Microsoft公司為UNICODE設(shè)計了Windows API,這樣,可以盡量減少對你的代碼的影響。實際上,你可以編寫單個源代碼文件,以便使用或者不使用UNICODE來對它進行編譯。只需要定義兩個宏(UNICODE_ UNICODE),就可以修改然后重新編譯該源文件。

2.8.1 C運行期庫對UNICODE的支持

為了利用UNICODE字符串,定義了一些數(shù)據(jù)類型。標(biāo)準的C頭文件String,h已經(jīng)作了修改,以便定義一個名字為wchart的數(shù)據(jù)類型,它是一個UNICODE字符的數(shù)據(jù)類型:

例如,如果想要創(chuàng)建一個緩存,用于存放最多為99個字符的UNICODE字符串和一個結(jié)尾為

零的字符,可以使用下面這個語句:

該語句創(chuàng)建了一個由10016位值組成的數(shù)組。當(dāng)然,標(biāo)準的C運行期字符串函數(shù),如

strcpy、strchrstrcat等,只能對ANSI字符串進行操作,不能正確地處理UNICODE字符串。因此,ANSI C也擁有一組補充函數(shù)。清單2 – 1顯示了一些標(biāo)準的ANSI C字符串函數(shù),后面是它們的等價UNICODE函數(shù)。

clip_image001

清單2-1 標(biāo)準的ANSI C字符串函數(shù)和它們的等價UNICODE函數(shù)

clip_image002

請注意,所有的UNICODE函數(shù)均以wcs開頭,wcs是寬字符串的英文縮寫。若要調(diào)用UNICODE函數(shù),只需用前綴wcs來取代ANSI字符串函數(shù)的前綴str即可。

 

注意       大多數(shù)軟件開發(fā)人員可能已經(jīng)不記得這樣一個非常重要的問題了,那就是

Microsoft公司提供的C運行期庫與ANSI的標(biāo)準C運行期庫是一致的。ANSI C規(guī)定,C運行期庫支持UNICODE字符和字符串。這意味著始終都可以調(diào)用C運行期函數(shù),以便對UNICODE字符和字符串進行操作,即使是在Windows 98上運行,也可以調(diào)用這些函數(shù)。換句話說, wcscatwcslenwcstok等函數(shù)都能夠在Windows 98上很好地運行,這些都是必須關(guān)心的操作系統(tǒng)函數(shù)。

對于包含了對str函數(shù)或wcs函數(shù)進行顯式調(diào)用的代碼來說,無法非常容易地同時為ANSIUNICODE對這些代碼進行編譯。本章前面說過,可以創(chuàng)建同時為ANSIUNICODE進行編譯的單個源代碼文件。若要建立雙重功能,必須包含TChar.h文件,而不是包含String,h文件。

TChar.h文件的唯一作用是幫助創(chuàng)建ANSI / UNICODE通用源代碼文件。它包含你應(yīng)該用在源代碼中的一組宏,而不應(yīng)該直接調(diào)用str函數(shù)或者wcs函數(shù)。如果在編譯源代碼文件時定義了_ UNICODE,這些宏就會引用wcs這組函數(shù)。如果沒有定義_ UNICODE,那么這些宏將引用str這組宏。

例如,在TChar.h中有一個宏稱為_tcscpy。如果在包含該頭文件時沒有定義_ UNICODE ,那么_tcscpy就會擴展為ANSIstrcpy函數(shù)。但是如果定義了_UNICODE, _tcscpy將擴展為UNICODEwcscpy函數(shù)。擁有字符串參數(shù)的所有C運行期函數(shù)都在TChar.h文件中定義了一個通用宏。如果使用通用宏,而不是ANSI / UNICODE的特定函數(shù)名,就能夠順利地創(chuàng)建可以為ANSIUNICODE進行編譯的源代碼。

但是,除了使用這些宏之外,還有一些操作是必須進行的。TChar.h文件包含了另外一些宏。若要定義一個ANSI / UNICODE通用的字符串?dāng)?shù)組,請使用下面的TCHAR數(shù)據(jù)類型。如果定義了_ UNICODE,TCHAR將聲明為下面的形式:

clip_image003

使用該數(shù)據(jù)類型,可以像下面這樣分配一個字符串:

clip_image004

也可以創(chuàng)建對字符串的指針:

clip_image005

不過上面這行代碼存在一個問題。按照默認設(shè)置, Microsoft公司的C + +編譯器能夠編譯所有的字符串,就像它們是ANSI字符串,而不是UNICODE字符串。因此,如果沒有定義_ UNICODE,該編譯器將能正確地編譯這一行代碼。但是,如果定義了_ UNICODE,就會產(chǎn)生一個錯誤。若要生成一個UNICODE字符串而不是ANSI字符串,必須將該代碼行改寫為下面的樣子:

clip_image006

字符串(literal string)前面的大寫字母L,用于告訴編譯器該字符串應(yīng)該作為UNICODE字符串來編譯。當(dāng)編譯器將字符串置于程序的數(shù)據(jù)部分中時,它在每個字符之間分散插入零字節(jié)。這種變更帶來的問題是,現(xiàn)在只有當(dāng)定義了_ UNICODE時,程序才能成功地進行編譯。我們需要另一個宏,以便有選擇地在字符串的前面加上大寫字母L。這項工作由_TEXT宏來完成,_TEXT宏也在TChar.h文件中做了定義。如果定義了_ UNICODE,那么_TEXT定義為下面的形式:

clip_image007

如果沒有定義_ UNICODE_TEXT將定義為

clip_image008

使用該宏,可以改寫上面這行代碼,這樣,無論是否定義了_ UNICODE宏,它都能夠正確地進行編譯。如下所示:

clip_image009

_TEXT宏也可以用于字符串。例如,若要檢查一個字符串的第一個字符是否是大寫字母J,只需編寫下面的代碼即可:

clip_image010

2.8.2 Windows定義的UNICODE數(shù)據(jù)類型

Windows頭文件定義了表2 – 3列出的數(shù)據(jù)類型。

2-3 Uincode 數(shù)據(jù)類型

clip_image012

這些數(shù)據(jù)類型是指UNICODE字符和字符串。Windows頭文件也定義了ANSI / UNICODE通用數(shù)據(jù)類型P T STRP C T STR。這些數(shù)據(jù)類型既可以指ANSI字符串,也可以指UNICODE字符串,這取決于當(dāng)編譯程序模塊時是否定義了UNICODE宏。請注意,這里的UNICODE宏沒有前置的下劃線。_ UNICODE宏用于C運行期頭文件,而UNICODE宏則用于Windows頭文件。當(dāng)編譯源代碼模塊時,通常必須同時定義這兩個宏。

2.8.3 Windows中的UNICODE函數(shù)和ANSI函數(shù)

前面已經(jīng)講過,有兩個函數(shù)稱為CreateWindowEx,一個CreateWindowEx接受UNICODE字符串,另一個CreateWindowEx接受ANSI字符串。情況確實如此,不過,這兩個函數(shù)的原型實際上是下面的樣子:

clip_image013

clip_image014

CreateWindowEx W是接受UNICODE字符串的函數(shù)版本。函數(shù)名結(jié)尾處的大寫字母W是英文wide()的縮寫。每個UNICODE字符的長度是1 6位,因此,它們常常稱為寬字符。CreateWindowEx A的結(jié)尾處的大寫字母A表示該函數(shù)可以接受ANSI字符串。

但是,在我們的代碼中,通常只包含了對CreateWindowEx的調(diào)用,而不是直接調(diào)用CreateWindowEx W或者CreateWindowEx A。在Wi n U s e r. h文件中,CreateWindowEx實際上是定義為下面這種形式的一個宏:

clip_image015

當(dāng)編譯源代碼模塊時, UNICODE 是否已經(jīng)作了定義,將決定你調(diào)用的是哪CreateWindowEx版本。當(dāng)轉(zhuǎn)用一個1 6位的Windows應(yīng)用程序時,你在編譯期間可能沒有定義UNICODE。對CreateWindowEx函數(shù)的任何調(diào)用都會將該宏擴展為對CreateWindowEx A的調(diào)用,即對CreateWindowExANSI版本的調(diào)用。由于1 6Windows只提供了CreateWindowExANSI版本,因此可以比較容易地轉(zhuǎn)用它的應(yīng)用程序。

Windows 2000下,MicrosoftCreateWindowEx A源代碼只不過是一個形實替換程序?qū)踊?/SPAN>

翻譯層,用于分配內(nèi)存,以便將ANSI字符串轉(zhuǎn)換成UNICODE字符串。該代碼然后調(diào)用CreateWindowEx,并傳遞轉(zhuǎn)換后的字符串。當(dāng)CreateWindowEx W返回時,CreateWindowEx A便釋放它的內(nèi)存緩存,并將窗口句柄返回給你。

如果要創(chuàng)建其他軟件開發(fā)人員將要使用的動態(tài)鏈接庫(DLL),請考慮使用下面的方法。在D L L中提供兩個輸出函數(shù)。一個是ANSI版本,另一個是UNICODE版本。在ANSI版本中,只需要分配內(nèi)存,執(zhí)行必要的字符串轉(zhuǎn)換,并調(diào)用該函數(shù)的UNICODE版本(本章后面部分介紹這個進程)。

Windows 98下,MicrosoftCreateWindowEx A源代碼是執(zhí)行操作的函數(shù)。Windows 98

提供了接受UNICODE參數(shù)的所有Windows函數(shù)的進入點,但是這些函數(shù)并不將UNICODE字符串轉(zhuǎn)換成ANSI字符串,它們只返回運行失敗的消息。調(diào)用GetLastError將返ERROR_CALLNOTIMPLEMENTED。這些函數(shù)中只有ANSI版本的函數(shù)才能正確地運行。如果編譯的代碼調(diào)用了任何寬字符函數(shù),應(yīng)用程序?qū)o法在Windows 98下運行。

Windows API中的某些函數(shù),比如WinExecOpenFile等,只是為了實現(xiàn)與1 6Windows程序的向后兼容而存在,因此,應(yīng)該避免使用。應(yīng)該使用對CreateProcessCreateFile函數(shù)的調(diào)用來取代對WinExecOpenFile函數(shù)的調(diào)用。從系統(tǒng)內(nèi)部來講,老的函數(shù)完全可以調(diào)用新的函數(shù)。老的函數(shù)存在的一個大問題是,它們不接受UNICODE字符串。當(dāng)調(diào)用這些函數(shù)時,必須傳遞ANSI字符串。另一方面,所有新的和未過時的函數(shù)在Windows 2000中都同時擁有ANSIUNICODE兩個版本。

2.8.4 Windows字符串函數(shù)

Windows還提供了一組范圍很廣的字符串操作函數(shù)。這些函數(shù)與C運行期字符串函數(shù)(如strcpywcscpy)很相似。但是該操作系統(tǒng)函數(shù)是操作系統(tǒng)的一個組成部分,操作系統(tǒng)的許多組件都使用這些函數(shù),而不使用C運行期庫。建議最好使用操作系統(tǒng)函數(shù),而不要使用C運行期字符串函數(shù)。這將有助于稍稍提高你的應(yīng)用程序的運行性能,因為操作系統(tǒng)字符串函數(shù)常常被大型應(yīng)用程序比如操作系統(tǒng)的外殼進程Explorer.exe所使用。由于這些函數(shù)使用得很多,因此,在你的應(yīng)用程序運行時,它們可能已經(jīng)被裝入RAM。

若要使用這些函數(shù),系統(tǒng)必須運行Windows 2000Windows 98。如果安裝了InternetExplorer 4.0或更新的版本,也可以在較早的Windows版本中獲得這些函數(shù)。在經(jīng)典的操作系統(tǒng)函數(shù)樣式中,操作系統(tǒng)字符串函數(shù)名既包含大寫字母,也包含小寫字母,它的形式類似這個樣子: Strcat、Strchr、StrCmpStrcpy等。若要使用這些函數(shù),必須加上S h l WA p i . h頭文件。另外,如前所述,這些字符串函數(shù)既有ANSI版本,也有UNICODE版本,例如Strcat AStrcat W。由于這些函數(shù)屬于操作系統(tǒng)函數(shù),因此,當(dāng)創(chuàng)建應(yīng)用程序時,如果定義了UNICODE(不帶前置下劃線),那么它們的符號將擴展為寬字符版本。

2.9 成為符合ANSIUNICODE的應(yīng)用程序

即使你不打算立即使用UNICODE,最好也應(yīng)該著手將你的應(yīng)用程序轉(zhuǎn)換成符合UNICODE的應(yīng)

用程序。下面是應(yīng)該遵循的一些基本原則:

將文本串視為字符數(shù)組,而不是c h a r s數(shù)組或字節(jié)數(shù)組。

將通用數(shù)據(jù)類型(如TCHARP T STR)用于文本字符和字符串。

將顯式數(shù)據(jù)類型(如B Y T EP B Y T E)用于字節(jié)、字節(jié)指針和數(shù)據(jù)緩存。

T E X T宏用于原義字符和字符串。

執(zhí)行全局性替換(例如用P T STR替換P STR)。

修改字符串運算問題。例如函數(shù)通常希望你在字符中傳遞一個緩存的大小,而不是字節(jié)。

這意味著你不應(yīng)該傳遞s i z e o f ( s z B u ff e r ) ,而應(yīng)該傳遞( s i z e o f ( s z B u ff e r ) / s i z e o f ( TCHAR )。另外,

如果需要為字符串分配一個內(nèi)存塊,并且擁有該字符串中的字符數(shù)目,那么請記住要按字節(jié)來分配內(nèi)存。這就是說,應(yīng)該調(diào)用malloc(nCharacters *sizeof(TCHAR)), 而不是調(diào)用malloc(nChar acters )。在上面所說的所有原則中,這是最難記住的一條原則,如果操作錯誤,編譯器

將不發(fā)出任何警告。

當(dāng)我為本書的第一版編寫示例程序時,我編寫的原始程序只能編譯為ANSI程序。后來,當(dāng)我開始撰寫本章的內(nèi)容時,我想我應(yīng)該鼓勵使用UNICODE,并且打算創(chuàng)建一些示例程序,以便展示你可以非常容易地編寫既可以用UNICODE也可以用ANSI來編譯的程序。這時我發(fā)現(xiàn)最好的辦法是將本書的所有示例程序進行轉(zhuǎn)換,使它們都能夠用UNICODEANSI進行編譯。我用了大約4個小時將所有程序進行了轉(zhuǎn)換。考慮到我以前從來沒有這方面的轉(zhuǎn)換經(jīng)驗,這個速度是相當(dāng)不錯了。

2.9.1 Windows字符串函數(shù)

Win d o w s也提供了一組用于對UNICODE字符串進行操作的函數(shù),表2 – 4對它們進行了描述。

clip_image017

這些函數(shù)是作為宏來實現(xiàn)的,這些宏既可以調(diào)用函數(shù)的UNICODE版本,也可以調(diào)用函數(shù)的ANSI版本,這要根據(jù)編譯源代碼模塊時是否已經(jīng)定義了UNICODE而定。例如,如果沒有定義UNICODE,l strcat函數(shù)將擴展為l strcat A。如果定義了UNICODE,l strcat將擴展為l strcat W。有兩個字符串函數(shù),即l StrCmpl StrCmp i,它們的行為特性與等價的C運行期函數(shù)是不同的。C運行期函數(shù)StrCmp、StrCmpiwcscmpwcscmpi只是對字符串中的代碼點的值進行比較這

就是說,這些函數(shù)將忽略實際字符的含義,只是將第一個字符串中的每個字符的數(shù)值與第二個

字符串中的字符的數(shù)值進行比較。而Windows函數(shù)l StrCmpl StrCmpi是作為對Windows函數(shù)CompareString的調(diào)用來實現(xiàn)的。

clip_image018

該函數(shù)對兩個UNICODE字符串進行比較。CompareString的第一個參數(shù)用于設(shè)定語言IDLCID),這是個3 2位值,用于標(biāo)識一種特定的語言。CompareString使用這個LCID來比較這兩個字符串,方法是對照一種特定的語言來查看它們的字符的含義。這種操作方法比C運行期函數(shù)簡單地進行數(shù)值比較更有意義。

當(dāng)l StrCmp函數(shù)系列中的任何一個函數(shù)調(diào)用CompareString時,該函數(shù)便將調(diào)用Windows

GetTheadString函數(shù)的結(jié)果作為第一個參數(shù)來傳遞:

clip_image019

每次創(chuàng)建一個線程時,它就被賦予一種語言。函數(shù)將返回該線程的當(dāng)前語言設(shè)置。CompareString的第二個參數(shù)用于標(biāo)識一些標(biāo)志,這些標(biāo)志用來修改該函數(shù)比較兩個字符串時所用的方法。表2 – 5顯示了可以使用的標(biāo)志。

clip_image021

當(dāng)l StrCmp調(diào)用CompareString時,它傳遞0作為fdwStyle的參數(shù)。但是,當(dāng)lStrCmp i調(diào)用CompareString時,它就傳遞NORMIGNORECASE。CompareString的其余4個參數(shù)用于設(shè)定兩個字符串和它們各自的長度。如果為cch1參數(shù)傳遞- 1,那么該函數(shù)將認為pString1字符串是以0結(jié)尾,并計算該字符串的長度。對于pString2字符串來說,參數(shù)cch2的作用也是一樣。其他C運行期函數(shù)沒有為UNICODE字符串的操作提供很好的支持。例如,tolowertoupper函數(shù)無法正確地轉(zhuǎn)換帶有重音符號的字符。為了彌補C運行期庫中的這些不足,必須調(diào)用下面這些Windows函數(shù),以便轉(zhuǎn)換UNICODE字符串的大小寫字母。這些函數(shù)也可以正確地用于ANSI字符串。頭兩個函數(shù):

clip_image022

既可以轉(zhuǎn)換單個字符,也可以轉(zhuǎn)換以0結(jié)尾的整個字符串。若要轉(zhuǎn)換整個字符串,只需要傳遞字符串的地址即可。若要轉(zhuǎn)換單個字符,必須像下面這樣傳遞各個字符:

clip_image024

6位包含了該字符,較高的1 6位包含0。當(dāng)該函數(shù)看到較高位是0時,該函數(shù)就知道你想要轉(zhuǎn)換單個字符,而不是整個字符串。返回的值是個3 2位值,較低的1 6位中是已經(jīng)轉(zhuǎn)換的字符。下面兩個函數(shù)與前面兩個函數(shù)很相似,差別在于它們用于轉(zhuǎn)換緩存中包含的字符(該緩存不必以0結(jié)尾):

clip_image025

其他的C運行期函數(shù),如isalpha、islowerisupper,返回一個值,指明某個字符是字母字符、小寫字母還是大寫字母。Windows API 提供了一些函數(shù),也能返回這些信息,但是Windows函數(shù)也要考慮用戶在控制面板中指定的語言:

clip_image026

printf函數(shù)家族是要介紹的最后一組C運行期函數(shù)。如果在定義了_ UNICODE的情況下編譯你的源代碼模塊,那么printf函數(shù)家族便希望所有字符和字符串參數(shù)代表UNICODE字符和字符串。但是,如果在沒有定義_ UNICODE的情況下編譯你的源代碼模塊, printf函數(shù)家族便希望傳遞

給它的所有字符和字符串都是ANSI字符和字符串。Microsoft公司已經(jīng)給C運行期的printf函數(shù)家族增加了一些特殊的域類型。其中有些域類型尚未被ANSIC采用。新類型使你能夠很容易地對ANSIUNICODE字符和字符串進行混合和匹配。

操作系統(tǒng)的w s printf函數(shù)也得到了增強。下面是一些例子(請注意大寫S和小寫s的使用):

clip_image027

clip_image028

2.9.2 資源

當(dāng)資源編譯器對你的所有資源進行編譯時,輸出文件是資源的二進制文件。資源(字符串表、對話框模板和菜單等)中的字符串值總是寫作UNICODE字符串。在Windows 98Windows2000下,如果應(yīng)用程序沒有定義UNICODE宏,那么系統(tǒng)就會進行內(nèi)部轉(zhuǎn)換。

例如,如果在編譯源代碼模塊時沒有定義UNICODE,調(diào)用LoadString實際上就是調(diào)用LoadString A函數(shù)。這時LoadString A就從你的資源中讀取字符串,并將該字符串轉(zhuǎn)換成ANSI字符串。ANSI形式的字符串將從該函數(shù)返回給你的應(yīng)用程序。

2.9.3 確定文本是ANSI文本還是UNICODE文本

到現(xiàn)在為止,UNICODE文本文件仍然非常少。實際上, Microsoft公司自己的大多數(shù)產(chǎn)品并沒有配備任何UNICODE文本文件。但是預(yù)計將來這種情況是會改變的(盡管這需要一個很長的過程)。當(dāng)然,Windows 2000Notepad (記事本)應(yīng)用程序允許你既能打開UNICODE文件,也能打開ANSI文件,并且可以創(chuàng)建這些文件。圖2 – 1顯示了NotepadSave As(文件另存為)對話框。請注意可以用不同的方法來保存文本文件。

clip_image030

對于許多用來打開文本文件和處理這些文件的應(yīng)用程序(如編譯器)來說,打開一個文件后,應(yīng)用程序就能方便地確定該文本文件是包含ANSI字符還是UNICODE字符。IsTest UNICODE函數(shù)能夠幫助進行這種區(qū)分:

clip_image032

文本文件存在的問題是,它們的內(nèi)容沒有嚴格和明確的規(guī)則,因此很難確定該文件是包含ANSI字符還是UNICODE字符。IsTest UNICODE使用一系列統(tǒng)計方法和定性方法,以便猜測緩存的內(nèi)容。由于這不是一種確切的科學(xué)方法,因此IsTest UNICODE有可能返回不正確的結(jié)果。第一個參數(shù)pvBuffer用于標(biāo)識要測試的緩存的地址。該數(shù)據(jù)是個無效指針,因為你不知道你擁有的是ANSI字符數(shù)組還是UNICODE字符數(shù)組。

第二個參數(shù)c b用于設(shè)定pvBuffer指向的字節(jié)數(shù)。同樣,由于你不知道緩存中放的是什么,因此c b是個字節(jié)數(shù),而不是字符數(shù)。請注意,不必設(shè)定緩存的整個長度。當(dāng)然, IsTest UNICODE能夠測試的字節(jié)越多,得到的結(jié)果越準確。

第三個參數(shù)pResult是個整數(shù)的地址,必須在調(diào)用IsTest UNICODE之前對它進行初始化。對該整數(shù)進行初始化后,就可以指明你要IsTest UNICODE執(zhí)行哪些測試。也可以為該參數(shù)傳遞NULL,在這種情況下,IsTest UNICODE將執(zhí)行它能夠進行的所有測試(詳細說明請參見Platform SDK文檔)。

如果IsTest UNICODE認為緩存包含UNICODE文本,便返回TRUE,否則返回FALSE。確實是這樣,盡管Microsoft將該函數(shù)的原型規(guī)定為返回D W O R D,但是它實際上返回一個布爾值。如果在pResult參數(shù)指向的整數(shù)中必須進行特定的測試,該函數(shù)就會在返回之前設(shè)定整數(shù)中的信息位,以反映每個測試的結(jié)果。

Windows98 Windows 98下,IsTest UNICODE函數(shù)沒有有用的實現(xiàn)代碼,它只是返回FALSE。調(diào)用GetLastError函數(shù)將返回E R R O R C A L L N O T I M P L E M E N T D。

 

2.9.4 UNICODEANSI之間轉(zhuǎn)換字符串

Windows函數(shù)MultiByteToWideChar用于將多字節(jié)字符串轉(zhuǎn)換成寬字符串。下面顯示了MultiByteToWideChar函數(shù)。

clip_image033

uCodePage參數(shù)用于標(biāo)識一個與多字節(jié)字符串相關(guān)的代碼頁號。dwFlags參數(shù)用于設(shè)定另一個控件,它可以用重音符號之類的區(qū)分標(biāo)記來影響字符。這些標(biāo)志通常并不使用,在dwFlags參數(shù)中傳遞0。pMultiByteStr參數(shù)用于設(shè)定要轉(zhuǎn)換的字符串, cchMultiByte參數(shù)用于指明該字符串的長度(按字節(jié)計算)。如果為cchMultiByte參數(shù)傳遞- 1,那么該函數(shù)用于確定源字符串的長

度。

轉(zhuǎn)換后產(chǎn)生的UNICODE版本字符串將被寫入內(nèi)存中的緩存,其地址由pWideCharStr參數(shù)指定。必須在cchWideChar參數(shù)中設(shè)定該緩存的最大值(以字符為計量單位)。如果調(diào)用MultiByteToWideChar,給cchWideChar參數(shù)傳遞0,那么該參數(shù)將不執(zhí)行字符串的轉(zhuǎn)換,而是返回為使轉(zhuǎn)換取得成功所需要的緩存的值。一般來說,可以通過下列步驟將多字節(jié)字符串轉(zhuǎn)換

UNICODE等價字符串:

1) 調(diào)用MultiByteToWideChar函數(shù),為pWideCharStr參數(shù)傳遞NULL,為cchWideChar參數(shù)

傳遞0

2) 分配足夠的內(nèi)存塊,用于存放轉(zhuǎn)換后的UNICODE字符串。該內(nèi)存塊的大小由前面對M u l t B y t e To Wi d e C h a r的調(diào)用返回。

3) 再次調(diào)用MultiByteToWideChar,這次將緩存的地址作為pWideCharStr參數(shù)來傳遞,并傳遞第一次調(diào)用MultiByteToWideChar時返回的緩存大小,作為cchWideChar參數(shù)。

4. 使用轉(zhuǎn)換后的字符串。

5) 釋放UNICODE字符串占用的內(nèi)存塊。函數(shù)WideCharToMultiByte將寬字符串轉(zhuǎn)換成等價的多字節(jié)字符串,如下所示:

clip_image034

該函數(shù)與MultiByteToWideChar函數(shù)相似。同樣,uCodePage參數(shù)用于標(biāo)識與新轉(zhuǎn)換的字符串相關(guān)的代碼頁。dwFlags則設(shè)定用于轉(zhuǎn)換的其他控件。這些標(biāo)志能夠作用于帶有區(qū)分符號的字符和系統(tǒng)不能轉(zhuǎn)換的字符。通常不需要為字符串的轉(zhuǎn)換而擁有這種程度的控制手段,你將為dwFlags參數(shù)傳遞0。pWideCharStr參數(shù)用于設(shè)定要轉(zhuǎn)換的字符串的內(nèi)存地址,cchWideChar參數(shù)用于指明該字符串的長度(用字符數(shù)來計量)。如果你為cchWideChar參數(shù)傳遞- 1,那么該函數(shù)用于確定源字符串的長度。

轉(zhuǎn)換產(chǎn)生的多字節(jié)版本的字符串被寫入由pMultiByteStr參數(shù)指明的緩存。必須在cchMultiByte參數(shù)中設(shè)定該緩存的最大值(用字節(jié)來計量)。如果傳遞0作為WideCharToMultiByte函數(shù)的cchMultiByte參數(shù),那么該函數(shù)將返回目標(biāo)緩存需要的大小值。通常可以使用將多字節(jié)字符串轉(zhuǎn)換成寬字節(jié)字符串時介紹的一系列類似的事件,將寬字節(jié)字符串轉(zhuǎn)換成多字節(jié)字符串。你會發(fā)現(xiàn),WideCharToMultiByte函數(shù)接受的參數(shù)比MultiByteToWideChar函數(shù)要多2個,即pDefaulTCHARpfUsedDefaulTCHAR。只有當(dāng)WideCharToMultiByte函數(shù)遇到一個寬字節(jié)字符,而該字符在uCodePage參數(shù)標(biāo)識的代碼頁中并沒有它的表示法時,WideCharToMultiByte函數(shù)才使用這兩個參數(shù)。如果寬字節(jié)字符不能被轉(zhuǎn)換,該函數(shù)便使用pDefaulTCHAR參數(shù)指向的字符。如果該參數(shù)是NULL(這是大多數(shù)情況下的參數(shù)值),那么該函數(shù)使用系統(tǒng)的默認字符。該默認字符通常是個問號。這對于文件名來說是危險的,因為問號是個通配符。pfUsedDefaulTCHAR參數(shù)指向一個布爾變量,如果寬字符串中至少有一個字符不能轉(zhuǎn)換成等價多字節(jié)字符,那么函數(shù)就將該變量置為TRUE。如果所有字符均被成功地轉(zhuǎn)換,那么該函數(shù)就將該變量置為FALSE。當(dāng)函數(shù)返回以便檢查寬字節(jié)字符串是否被成功地轉(zhuǎn)換后,可以測試該變量。同樣,通常為該測試傳遞NULL。

關(guān)于如何使用這些函數(shù)的詳細說明,請參見Platform SDK文檔。

如果使用這兩個函數(shù),就可以很容易創(chuàng)建這些函數(shù)的UNICODE版本和ANSI版本。例如,你

可能有一個動態(tài)鏈接庫,它包含一個函數(shù),能夠轉(zhuǎn)換字符串中的所有字符??梢韵裣旅孢@樣編寫該函數(shù)的UNICODE版本:

clip_image036

clip_image038

你可以編寫該函數(shù)的ANSI版本以便該函數(shù)根本不執(zhí)行轉(zhuǎn)換字符串的實際操作。你也可以編寫該函數(shù)的ANSI版本,以便該函數(shù)它將ANSI字符串轉(zhuǎn)換成UNICODE字符串,將UNICODE字符串傳遞給StringReverseW函數(shù),然后將轉(zhuǎn)換后的字符串重新轉(zhuǎn)換成ANSI字符串。該函數(shù)類似下面的樣子:

clip_image040

clip_image041

clip_image043

最后,在用動態(tài)鏈接庫分配的頭文件中,可以像下面這樣建立這兩個函數(shù)的原型:

clip_image044

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多