• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            C++ Programmer's Cookbook

            {C++ 基礎(chǔ)} {C++ 高級} {C#界面,C++核心算法} {設(shè)計模式} {C#基礎(chǔ)}

            windows核心編程--字符集

             字符unicode與windows

             
            1 軟件的本地化要解決的真正問題,實際上就是如何來處理不同的字符集。以前我們習(xí)慣與用單字節(jié)字符集來編程.
            2 單字符集:將文本串作為一系列單字節(jié)字符來進(jìn)行編碼,并在結(jié)尾處放上一個零。(每個字符用一個字節(jié)來表示)
            3 雙字節(jié)字符集(D B C S ):在雙字節(jié)字符集中,字符串中的每個字符可以包含一個字節(jié)或包含兩個字節(jié)。
            4 unicode字符集:U n i c o d e 提供了一種簡單而又一致的表示字符串的方法。U n i c o d e 字符串中的所有字符都是1 6 位的(兩個字節(jié))。
            5 當(dāng)M i c r o s o f t 公司將C O M 從1 6 位Wi n d o w s 轉(zhuǎn)換成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 (記事本)應(yīng)用程序允許你既能打開U n i c o d e 文件,也能打開A N S I 文件,并且可以創(chuàng)建這些文件。
            8 I s Te x t U n i c o d e 函數(shù)能夠幫助進(jìn)行區(qū)分ANSIC字符和unicode:
            DWORD IsTextUnicode(CONST PVOID pvBuffer, int cb,PINT pResult);

            第一個參數(shù)p v B u ff e r 用于標(biāo)識要測試的緩存的地址。該數(shù)據(jù)是個無效指針,因為你不知道你擁有的是A N S I 字符數(shù)組還是U n i c o d e 
            字符數(shù)組。

            第二個參數(shù)c b 用于設(shè)定p v B u ff e r 指向的字節(jié)數(shù)。同樣,由于你不知道緩存中放的是什么,因此c b 是個字節(jié)數(shù),而不是字符數(shù)。請注意,不必設(shè)定緩存的整個長度。當(dāng)然,I s Te x t U n i c o d e能夠測試的字節(jié)越多,得到的結(jié)果越準(zhǔn)確。

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

            9 對D B C S 字符串進(jìn)行操作的幫助函數(shù)

            函數(shù) 描述
            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); 如果該字節(jié)是DBCS 字符的第一個字節(jié),則返回


            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 ,因此可以為任意一種開發(fā)應(yīng)用程序。

            • Windows 98 只支持A N S I ,只能為A N S I 開發(fā)應(yīng)用程序。

            • Windows CE 只支持U n i c o d e ,只能為U n i c o d e 開發(fā)應(yīng)用程序。

            11 Wi n d o w s 頭文件定義de Uincode 數(shù)據(jù)類型

            數(shù)據(jù)類型 說明
            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之間轉(zhuǎn)換字符串

            Wi n d o w s 函數(shù)M u l t i B y t e To Wi d e C h a r 用于將多字節(jié)字符串轉(zhuǎn)換成寬字符串。下面顯示了M u l t i B y t e To Wi d e C h a r 函數(shù)。

            int MultiByteToWideChar(
            UINT CodePage,          //code page
            DWORD dwFlags,          //character-type options
            LPCSTR lpMultiByteStr,  //address of string to map
            int cchMultiByte,       //number of bytes in string
            LPWSTR lpWideCharStr,   //address of wide-character buffer
            int cchWideChar         //size of buffer
            );
            u C o d e P a g e 參數(shù)用于標(biāo)識一個與多字節(jié)字符串相關(guān)的代碼頁號。d w F l a g s 參數(shù)用于設(shè)定另一個控件,它可以用重音符號之類的區(qū)分標(biāo)記來影響字符。這些標(biāo)志通常并不使用,在d w F l a g s參數(shù)中傳遞0 。p M u l t i B y t e S t r 參數(shù)用于設(shè)定要轉(zhuǎn)換的字符串,c c h M u l t i B y t e 參數(shù)用于指明該字符串的長度(按字節(jié)計算)。如果為c c h M u l t i B y t e 參數(shù)傳遞- 1 ,那么該函數(shù)用于確定源字符串的長度。

            轉(zhuǎn)換后產(chǎn)生的U n i c o d e 版本字符串將被寫入內(nèi)存中的緩存,其地址由p Wi d e C h a r S t r 參數(shù)指定。必須在c c h Wi d e C h a r 參數(shù)中設(shè)定該緩存的最大值(以字符為計量單位)。如果調(diào)用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 參數(shù)傳遞0 ,那么該參數(shù)將不執(zhí)行字符串的轉(zhuǎn)換,而是返回為使轉(zhuǎn)換取得成功所需要的緩存的值。一般來說,可以通過下列步驟將多字節(jié)字符串轉(zhuǎn)換成U n i c o d e 等價字符串:

            1) 調(diào)用M u l t i B y t e To Wi d e C h a r 函數(shù),為p Wi d e C h a r S t r 參數(shù)傳遞N U L L ,為c c h Wi d e C h a r 參數(shù)傳遞0 。
            2) 分配足夠的內(nèi)存塊,用于存放轉(zhuǎn)換后的U n i c o d e 字符串。該內(nèi)存塊的大小由前面對M u l t B y t e To Wi d e C h a r 的調(diào)用返回。
            3) 再次調(diào)用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 參數(shù)來傳遞,并傳遞第一次調(diào)用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 參數(shù)。
            4. 使用轉(zhuǎn)換后的字符串。
            5) 釋放U n i c o d e 字符串占用的內(nèi)存塊。
            函數(shù)Wi d e C h a r To M u l t i B y t e 將寬字符串轉(zhuǎn)換成等價的多字節(jié)字符串,如下所示:

            int WideCharToMultiByte(
            UINT CodePage,         // code page
            DWORD dwFlags,         // performance and mapping flags
            LPCWSTR lpWideCharStr, // address of wide-character string
            int cchWideChar,       // number of characters in string
            LPSTR lpMultiByteStr,  // address of buffer for new string
            int cchMultiByte,      // size of buffer
            LPCSTR lpDefaultChar,  // address of default for unmappable
            // characters
            LPBOOL lpUsedDefaultChar   // address of flag set when default
            // char. used
            );
            該函數(shù)與M u l t i B i t e To Wi d e C h a r 函數(shù)相似。同樣,u C o d e P a g e 參數(shù)用于標(biāo)識與新轉(zhuǎn)換的字符串相關(guān)的代碼頁。d w F l a g s 則設(shè)定用于轉(zhuǎn)換的其他控件。這些標(biāo)志能夠作用于帶有區(qū)分符號的字符和系統(tǒng)不能轉(zhuǎn)換的字符。通常不需要為字符串的轉(zhuǎn)換而擁有這種程度的控制手段,你將為d w F l a g s 參數(shù)傳遞0 。

            p Wi d e C h a r S t r 參數(shù)用于設(shè)定要轉(zhuǎn)換的字符串的內(nèi)存地址,c c h Wi d e C h a r 參數(shù)用于指明該字符串的長度(用字符數(shù)來計量)。如果你為c c h Wi d e C h a r 參數(shù)傳遞- 1 ,那么該函數(shù)用于確定源字符串的長度。

            轉(zhuǎn)換產(chǎn)生的多字節(jié)版本的字符串被寫入由p M u l t i B y t e S t r 參數(shù)指明的緩存。必須在c c h M u l t i B y t e參數(shù)中設(shè)定該緩存的最大值(用字節(jié)來計量)。如果傳遞0 作為Wi d e C h a r To M u l t i B y t e 函數(shù)的c c h M u l t i B y t e 參數(shù),那么該函數(shù)將返回目標(biāo)緩存需要的大小值。通??梢允褂脤⒍嘧止?jié)字符串轉(zhuǎn)換成寬字節(jié)字符串時介紹的一系列類似的事件,將寬字節(jié)字符串轉(zhuǎn)換成多字節(jié)字符串。

            你會發(fā)現(xiàn),Wi d e C h a r To M u l t i B y t e 函數(shù)接受的參數(shù)比M u l t i B y t e To Wi d e C h a r 函數(shù)要多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 。只有當(dāng)Wi d e C h a r To M u l t i B y t e 函數(shù)遇到一個寬字節(jié)字符,而該字符在u C o d e P a g e 參數(shù)標(biāo)識的代碼頁中并沒有它的表示法時,Wi d e C h a r To M u l t i B y t e 函數(shù)才使用這兩個參數(shù)。如果寬字節(jié)字符不能被轉(zhuǎn)換,該函數(shù)便使用p D e f a u l t C h a r 參數(shù)指向的字符。如果該參數(shù)是N U L L (這是大多數(shù)情況下的參數(shù)值),那么該函數(shù)使用系統(tǒng)的默認(rèn)字符。該默認(rèn)字符通常是個問號。這對于文件名來說是危險的,因為問號是個通配符。

            p f U s e d D e f a u l t C h a r 參數(shù)指向一個布爾變量,如果寬字符串中至少有一個字符不能轉(zhuǎn)換成等價多字節(jié)字符,那么函數(shù)就將該變量置為T R U E 。如果所有字符均被成功地轉(zhuǎn)換,那么該函數(shù)就將該變量置為FA L S E 。當(dāng)函數(shù)返回以便檢查寬字節(jié)字符串是否被成功地轉(zhuǎn)換后,可以測試該變量。同樣,通常為該測試傳遞N U L L 。

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

            如果使用這兩個函數(shù),就可以很容易創(chuàng)建這些函數(shù)的U n i c o d e 版本和A N S I 版本。例如,你可能有一個動態(tài)鏈接庫,它包含一個函數(shù),能夠轉(zhuǎn)換字符串中的所有字符。可以像下面這樣編寫該函數(shù)的U n i c o d e 版本:

            BOOL StringReverseW(PWSTR pWideCharStr)
            {
            //Get a pointer to the last character in the string.
            PWSTR pEndOfStr=pWideCharStr+wcslen(pWideCharStr)-1;
            wchar_t cCharT;
            //Repeat until we reach the center character
            //in the string.
            while (pWideCharStr < pEndOfStr)
            {
            //Save a character in a temporary variable.
            cCharT=*pWideCharStr;
            //Put the last character in the first character.
            *pWideCharStr =*pEndOfStr;
            //Put the temporary character in the last character.
            *pEndOfStr=cCharT;
            //Move in one character from the left.
            pWideCharStr++;
            //Move in one character from the right.
            pEndOfStr--;
            }
            //The string is reversed; return success.
            return(TRUE);
            }

            你可以編寫該函數(shù)的A N S I 版本以便該函數(shù)根本不執(zhí)行轉(zhuǎn)換字符串的實際操作。你也可以編寫該函數(shù)的A N S I 版本,以便該函數(shù)它將A N S I 字符串轉(zhuǎn)換成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 函數(shù),然后將轉(zhuǎn)換后的字符串重新轉(zhuǎn)換成A N S I 字符串。該函數(shù)類似下面的樣子:

             

            BOOL StringReverseA(PSTR pMultiByteStr)
            {
            PWSTR pWideCharStr;
            int nLenOfWideCharStr;
            BOOL fOk = FALSE;
            //Calculate the number of characters needed to hold
            //the wide_character version of string.
            nLenOfWideCharStr = MultiRyteToWideChar(CP_ACP, 0,
            pMultiByteStr, -1, NULL, 0);
            //Allocate memory from the process's default heap to
            //accommodate the size of the wide-character string.
            //Don't forget that MultiByteToWideChar returns the
            //number of characters,not the number of bytes,so
            //you must multiply by the size of wide character.
            pWideCharStr = HeapAlloc(GetProcessHeap(), 0,
            nLenOfWideCharStr * sizeof(WCHAR));
            if (pWideCharStr == NULL)
            return(fOk);
            //Convert the multibyte string to a wide_character string.
            MultiByteToWideChar(CP_ACP, 0, pMulti8yteStr, -1,
            pWideCharStr, nLenOfWideCharStr);
            //Call the wide-character version of this
            //function to do the actual work
            fOk = StnngReverseW(pWideCharStr);
            if (fOk)
            {
            //Convert the wide-character string back
            //to a multibyte string.
            WideCharToMultiByte(CP_ACP, 0, pWideCharStr, -1,
            pMultiByteStr, strlen(pMultiByteStr), NULL, NULL);
            }
            //Free the momory containing the wide-character string.
            HeapFree(GetProcessHeap(), 0, pWideCharStr);
            return(fOk),
            }
            最后,在用動態(tài)鏈接庫分配的頭文件中,可以像下面這樣建立這兩個函數(shù)的原型:

             

            BOOL StringReverseW (PWSTR pWideCharStr);
            BOOL StringReverseA (PSTR pMultiByteStr);
            #ifdef UNICODE
            #define StnngReverse StringReverseW
            #else
            #define StringRevcrsc StringReverseA
            #endif // UNICODE

            posted on 2006-09-11 16:57 夢在天涯 閱讀(1863) 評論(2)  編輯 收藏 引用 所屬分類: Windows API

            評論

            # re: windows核心編程--字符集 2006-09-12 08:50 笨笨

            大家都在搞核心編程??!這本書值得好好研究  回復(fù)  更多評論   

            # re: windows核心編程--字符集 2006-09-12 09:18 夢在天涯

            恩,是的,值的好好研究啊,很難啊,但是可以學(xué)到windows的工作原理,有助于更好地在windows上編程!  回復(fù)  更多評論   

            公告

            EMail:itech001#126.com

            導(dǎo)航

            統(tǒng)計

            • 隨筆 - 461
            • 文章 - 4
            • 評論 - 746
            • 引用 - 0

            常用鏈接

            隨筆分類

            隨筆檔案

            收藏夾

            Blogs

            c#(csharp)

            C++(cpp)

            Enlish

            Forums(bbs)

            My self

            Often go

            Useful Webs

            Xml/Uml/html

            搜索

            •  

            積分與排名

            • 積分 - 1804752
            • 排名 - 5

            最新評論

            閱讀排行榜

            91久久婷婷国产综合精品青草| 久久人人爽人人精品视频| 久久精品无码av| 品成人欧美大片久久国产欧美...| 久久亚洲AV成人出白浆无码国产| 色偷偷88欧美精品久久久| 精品久久久久久无码中文野结衣 | 青青青伊人色综合久久| 99久久国产热无码精品免费| 久久精品一本到99热免费| 久久精品国产亚洲AV高清热| 亚洲va国产va天堂va久久| 色综合久久综合中文综合网| 亚洲va久久久噜噜噜久久狠狠| 久久久精品2019免费观看| 国产精品久久久久久搜索| 久久国产精品99久久久久久老狼| 久久九九有精品国产23百花影院| 狠狠色婷婷综合天天久久丁香| 久久噜噜电影你懂的| 久久国产三级无码一区二区| 久久久久人妻精品一区三寸蜜桃| 三级片免费观看久久| 少妇久久久久久被弄高潮| 久久精品国产69国产精品亚洲| 日韩AV毛片精品久久久| 亚洲乱码精品久久久久.. | 99热精品久久只有精品| 久久伊人影视| 亚洲国产精品成人久久| 国产99久久久国产精品~~牛| 久久久久亚洲精品天堂久久久久久| 一级女性全黄久久生活片免费 | 欧美日韩中文字幕久久久不卡| 无码任你躁久久久久久老妇App| 久久久亚洲欧洲日产国码aⅴ| 国产精品免费久久久久影院| 人妻久久久一区二区三区| 久久久久人妻一区精品| 777米奇久久最新地址| 国产精品久久久久久久app |