乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

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

       天狼_順水推舟 2012-05-17

      UnicodeWindows編程(3)

      2.8 如何編寫UNICODE源代碼

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

      2.8.1 C運行期庫對UNICODE的支持

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

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

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

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

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

      clip_image001

      清單2-1 標準的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的標準C運行期庫是一致的。ANSI C規(guī)定,C運行期庫支持UNICODE字符和字符串。這意味著始終都可以調(diào)用C運行期函數(shù),以便對UNICODE字符和字符串進行操作,即使是在Windows 98上運行,也可以調(diào)用這些函數(shù)。換句話說, wcscat、wcslenwcstok等函數(shù)都能夠在Windows 98上很好地運行,這些都是必須關心的操作系統(tǒng)函數(shù)。

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

      TChar.h文件的唯一作用是幫助創(chuàng)建ANSI / UNICODE通用源代碼文件。它包含你應該用在源代碼中的一組宏,而不應該直接調(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通用的字符串數(shù)組,請使用下面的TCHAR數(shù)據(jù)類型。如果定義了_ UNICODETCHAR將聲明為下面的形式:

      clip_image003

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

      clip_image004

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

      clip_image005

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

      clip_image006

      字符串(literal string)前面的大寫字母L,用于告訴編譯器該字符串應該作為UNICODE字符串來編譯。當編譯器將字符串置于程序的數(shù)據(jù)部分中時,它在每個字符之間分散插入零字節(jié)。這種變更帶來的問題是,現(xiàn)在只有當定義了_ 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字符串,這取決于當編譯程序模塊時是否定義了UNICODE宏。請注意,這里的UNICODE宏沒有前置的下劃線。_ UNICODE宏用于C運行期頭文件,而UNICODE宏則用于Windows頭文件。當編譯源代碼模塊時,通常必須同時定義這兩個宏。

      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

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

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

      翻譯層,用于分配內(nèi)存,以便將ANSI字符串轉(zhuǎn)換成UNICODE字符串。該代碼然后調(diào)用CreateWindowEx,并傳遞轉(zhuǎn)換后的字符串。當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ù),應用程序?qū)o法在Windows 98下運行。

      Windows API中的某些函數(shù),比如WinExecOpenFile等,只是為了實現(xiàn)與1 6Windows程序的向后兼容而存在,因此,應該避免使用。應該使用對CreateProcessCreateFile函數(shù)的調(diào)用來取代對WinExecOpenFile函數(shù)的調(diào)用。從系統(tǒng)內(nèi)部來講,老的函數(shù)完全可以調(diào)用新的函數(shù)。老的函數(shù)存在的一個大問題是,它們不接受UNICODE字符串。當調(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ù)。這將有助于稍稍提高你的應用程序的運行性能,因為操作系統(tǒng)字符串函數(shù)常常被大型應用程序比如操作系統(tǒng)的外殼進程Explorer.exe所使用。由于這些函數(shù)使用得很多,因此,在你的應用程序運行時,它們可能已經(jīng)被裝入RAM。

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

      2.9 成為符合ANSIUNICODE的應用程序

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

      用程序。下面是應該遵循的一些基本原則:

      將文本串視為字符數(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é)。

      這意味著你不應該傳遞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 ( TCHAR )。另外,

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

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

      當我為本書的第一版編寫示例程序時,我編寫的原始程序只能編譯為ANSI程序。后來,當我開始撰寫本章的內(nèi)容時,我想我應該鼓勵使用UNICODE,并且打算創(chuàng)建一些示例程序,以便展示你可以非常容易地編寫既可以用UNICODE也可以用ANSI來編譯的程序。這時我發(fā)現(xiàn)最好的辦法是將本書的所有示例程序進行轉(zhuǎn)換,使它們都能夠用UNICODEANSI進行編譯。我用了大約4個小時將所有程序進行了轉(zhuǎn)換??紤]到我以前從來沒有這方面的轉(zhuǎn)換經(jī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而定。例如,如果沒有定義UNICODEl strcat函數(shù)將擴展為l strcat A。如果定義了UNICODE,l strcat將擴展為l strcat W。有兩個字符串函數(shù),即l StrCmpl StrCmp i,它們的行為特性與等價的C運行期函數(shù)是不同的。C運行期函數(shù)StrCmpStrCmpi、wcscmpwcscmpi只是對字符串中的代碼點的值進行比較這

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

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

      clip_image018

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

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

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

      clip_image019

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

      clip_image021

      l StrCmp調(diào)用CompareString時,它傳遞0作為fdwStyle的參數(shù)。但是,當lStrCmp i調(diào)用CompareString時,它就傳遞NORMIGNORECASECompareString的其余4個參數(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。當該函數(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 資源

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

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

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

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

      clip_image030

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

      clip_image032

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

      第二個參數(shù)c b用于設定pvBuffer指向的字節(jié)數(shù)。同樣,由于你不知道緩存中放的是什么,因此c b是個字節(jié)數(shù),而不是字符數(shù)。請注意,不必設定緩存的整個長度。當然, 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ù)中的信息位,以反映每個測試的結(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ù)用于標識一個與多字節(jié)字符串相關的代碼頁號。dwFlags參數(shù)用于設定另一個控件,它可以用重音符號之類的區(qū)分標記來影響字符。這些標志通常并不使用,在dwFlags參數(shù)中傳遞0pMultiByteStr參數(shù)用于設定要轉(zhuǎn)換的字符串, cchMultiByte參數(shù)用于指明該字符串的長度(按字節(jié)計算)。如果為cchMultiByte參數(shù)傳遞- 1,那么該函數(shù)用于確定源字符串的長

      度。

      轉(zhuǎn)換后產(chǎn)生的UNICODE版本字符串將被寫入內(nèi)存中的緩存,其地址由pWideCharStr參數(shù)指定。必須在cchWideChar參數(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ù)用于標識與新轉(zhuǎn)換的字符串相關的代碼頁。dwFlags則設定用于轉(zhuǎn)換的其他控件。這些標志能夠作用于帶有區(qū)分符號的字符和系統(tǒng)不能轉(zhuǎn)換的字符。通常不需要為字符串的轉(zhuǎn)換而擁有這種程度的控制手段,你將為dwFlags參數(shù)傳遞0。pWideCharStr參數(shù)用于設定要轉(zhuǎn)換的字符串的內(nèi)存地址,cchWideChar參數(shù)用于指明該字符串的長度(用字符數(shù)來計量)。如果你為cchWideChar參數(shù)傳遞- 1,那么該函數(shù)用于確定源字符串的長度。

      轉(zhuǎn)換產(chǎn)生的多字節(jié)版本的字符串被寫入由pMultiByteStr參數(shù)指明的緩存。必須在cchMultiByte參數(shù)中設定該緩存的最大值(用字節(jié)來計量)。如果傳遞0作為WideCharToMultiByte函數(shù)的cchMultiByte參數(shù),那么該函數(shù)將返回目標緩存需要的大小值。通??梢允褂脤⒍嘧止?jié)字符串轉(zhuǎn)換成寬字節(jié)字符串時介紹的一系列類似的事件,將寬字節(jié)字符串轉(zhuǎn)換成多字節(jié)字符串。你會發(fā)現(xiàn),WideCharToMultiByte函數(shù)接受的參數(shù)比MultiByteToWideChar函數(shù)要多2個,即pDefaulTCHARpfUsedDefaulTCHAR。只有當WideCharToMultiByte函數(shù)遇到一個寬字節(jié)字符,而該字符在uCodePage參數(shù)標識的代碼頁中并沒有它的表示法時,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。當函數(shù)返回以便檢查寬字節(jié)字符串是否被成功地轉(zhuǎn)換后,可以測試該變量。同樣,通常為該測試傳遞NULL。

      關于如何使用這些函數(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)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多