国际化开发技术FAQ
什么是國際化開發(fā)?
答:指應(yīng)用程序能夠支持不同的語言輸入和顯示,同時也能夠自如的適應(yīng)不同文化的習(xí)俗。
?
字節(jié)、字符、字符集和字符集編碼的關(guān)系?
答:計算機底層處理的最小單位是字節(jié)(8 位二進制表示)。
字符是表示一個有意義的符號或文字。
字符集是由一組相關(guān)的字符所組成的集合。比如說德文字符集只與德文相關(guān),中文字符集只與中文相關(guān),不會互相包含。
字符集編碼是解決字符在計算機中的編碼問題。
?
如何將字符集進行分類?
答:字符集編碼通常可以分為以下3 種:單字節(jié)編碼、寬字符編碼和多字節(jié)字符編碼。
??? 按照c/c++ 習(xí)慣,還可以分為:ANSI 字符集(單個/0 字符結(jié)尾)和寬字符集。
?
什么是 gb2312 字符集?
答:由原中國國家標準總局發(fā)布,1981 年5 月1 日實施,是中國國家標準的簡體中文字符集。它收錄了漢字及一般符號、序號、數(shù)字、拉丁字母、日文假名、希臘字母、俄文字母、漢語拼音符號、漢語注音字母,共7445 個圖形字符。
?
什么是 gbk 字符集?
答:GBK 最初是由微軟對GB2312 的擴展,也就是CP936 字碼表 (Code Page 936) 的擴展(原來的CP936 和GB 2312-80 一模一樣),最初出現(xiàn)于Windows 95 簡體中文版中,由于Windows 產(chǎn)品的流行和在大陸廣泛被使用,中華人民共和國國家有關(guān)部門將其作為技術(shù)規(guī)范。注意GBK 并非國家正式標準,只是國家技術(shù)監(jiān)督局標準化司、電子工業(yè)部科技與質(zhì)量監(jiān)督司發(fā)布的“技術(shù)規(guī)范指導(dǎo)性文件”。雖然 GBK 收錄了所有Unicode 1.1 及GB 13000.1-93 之中的漢字,但是編碼方式與Unicode 1.1 及GB 13000.1-93 不同。僅僅是GB 2312 到GB 13000.1-93 之間的過渡方案。GBK 收錄了21886 個符號,它分為漢字區(qū)和圖形符號區(qū)。漢字區(qū)包括21003 個字符。
?
什么是 GB18030 字符集?
答: 2000 年的GB18030 取代了GBK1.0 的正式國家標準。該標準收錄了27484 個漢字,同時還收錄了藏文、蒙文、維吾爾文等主要的少數(shù)民族文字。現(xiàn)在的PC 平臺必須支持GB18030 ,對嵌入式產(chǎn)品暫不作要求。所以手機、MP3 一般只支持GB2312 。
?
什么是 BIG5 字符集?
答: 大五碼(Big5 ),又稱為五大碼,是使用繁體 中文社群中最常用的電腦漢字字符集 標 準,共收錄13,060 個中文字,其中有二字為重覆編碼,Big5 屬中文內(nèi)碼(中文碼分為中文內(nèi)碼及中文交換碼兩類)。Big5 雖普及于臺灣、香港與澳門 等繁體中文通行區(qū),但長期以來并非當(dāng)?shù)氐膰覙藴?#xff0c;而只是業(yè)界標準(de facto standard )。倚天中文系統(tǒng)、Windows 等主要系統(tǒng)的字符集都是以Big5 為基準,但廠商又各自增刪,衍生成多種不同版本。
??? 2003 年,Big5 被收錄到臺灣官方標準的附錄當(dāng)中,取得了較正式的地位。這個最新版本被稱為Big5-2003 。
?
什么是 “ 許蓋功 ”問題?如何解決?
答:Big5碼 是雙字節(jié)字符集,使用了雙 字符 儲存方法,以兩個字節(jié)來安放一個字。第一個字節(jié)稱為「高位字節(jié)」,第二個字節(jié)稱為「低位字節(jié)」。“ 高位字節(jié)” 使用了0x81-0xFE ,“ 低位字節(jié)” 使用了0x40-0x7E ,及0xA1-0xFE 。
在Big5 的分區(qū)中:
| 0x8140-0xA0FE | 保留給使用者自定義字元(造字區(qū)) |
| 0xA140-0xA3BF | 標點符號、希臘字母 及特殊符號, |
| 0xA3C0-0xA3FE | 保留。此區(qū)沒有開放作造字區(qū)用。 |
| 0xA440-0xC67E | 常用漢字,先按筆劃 再按部首 排序。 |
| 0xC6A1-0xC8FE | 保留給使用者自定義字元(造字區(qū)) |
| 0xC940-0xF9D5 | 次常用漢字,亦是先按筆劃再按部首排序。 |
| 0xF9D6-0xFEFE | 保留給使用者自定義字元(造字區(qū)) |
??? 如其他DBCS 字符集相同,普通ASCII (小于0x80 )采用一個字節(jié)表示,這與雙字節(jié)的低字節(jié)部分有重疊。
??? 因為低位 字符 中包含了程序 、shell 、script 中,字串或命令常會用到的特殊字元,例如0x5C “/” 、0x7C “|” 等。「/ 」 在許多用途的字串中是當(dāng)作轉(zhuǎn)義符號又稱為跳脫 字符 ,例如 /n (換行)、/r (歸位) 、/t (tab )、// (/ 本身符號)、/" (引號)等等。而 「| 」 在UNIX 作業(yè)系統(tǒng)中大多當(dāng)作命令管線的使用,如 "ls -la | more" 等等。如果在字串中有這些特殊的轉(zhuǎn)義字元,會被程序或編譯器解釋為特殊用途。但是因為是中文的原因,故無法正確解釋為上面所述的行為,因此程式可能會忽略此轉(zhuǎn)義符號或是中斷執(zhí)行。若此,就違反了使用者本來要當(dāng)成中文字元一部份使用的本意。
??? 在常用字如「功」(0xA55C) 、「-( 許)- 」(0xB35C) 、「蓋」(0xBB5C) 、「育」(0xA87C) 中時常出現(xiàn),造成了許多軟體無法正確處理以Big5 編碼的字串或文件。這個問題被戲謔性地人名化,稱為「-( 許功蓋)- 」或「-( 許蓋功)- 」( 這三個字都有這種問題) 。
??? 一般的解決方法,是額外增加“/” 的字元,因為“//” 會被解釋為“/” ,所以“ 成功/ 因素” 這個字串就能無誤地被程式當(dāng)作“ 成功因素” 的字串來處理。 但是額外的困擾是,有些輸出功能并不會把“/” 當(dāng)作特殊字元看待,所以有些程式或網(wǎng)頁就會錯誤地常常出現(xiàn)在「許功蓋」這些字后面多了“/” 。
?
什么是 HKSCS 字符集?
答:HKSCS 是中國香港增補字符集,是以big5 為基礎(chǔ)進行擴充的。增加了一些粵語方言字和地名等。
?
什么是 UTF-8 字符集?
答:UTF-8 (8 位元 Universal Character Set /Unicode Transformation Format )是一種針對 Unicode 的可變長度字符編碼 。它可以用來表示 Unicode 標準中的任何字符,且其編碼中的第一個字節(jié) 仍與 ASCII 相容,這使得原來處理 ASCII 字符的軟件 無須或只須做少部份修改,即可繼續(xù)使用。因此,它逐漸成為電子郵件 、網(wǎng)頁 及其他儲存 或傳送文字的應(yīng)用中,優(yōu)先采用的編碼。
?
什么是 UTF-16 字符集?
答: UTF-16 是unicode 的缺省編碼方式,不兼容ASCII 碼,所有字符都是占用兩個字節(jié)。存在大小端的問題,一般用于本地存儲和顯示。
?
什么是 UTF-32 字符集?
答: UTF-32 一般用于UCS-4 ,采用4 字節(jié)編碼方式,目前很少用到。UTF-32 與UTF-16 一樣存在大小端的問題。
什么是 BOM ?
答: Unicode 規(guī)范中推薦的標記字節(jié)順序的方法是BOM 。BOM 不是“Bill Of Material” 的BOM 表,而是Byte Order Mark 。BOM 是一個有點小聰明的想法:
在UCS 編碼中有一個叫做”ZERO WIDTH NO-BREAK SPACE” 的字符,它的編碼是FEFF 。而FFFE 在UCS 中是不存在的字符,所以不應(yīng)該出現(xiàn)在實際傳輸中。UCS 規(guī)范建議我們在傳輸字節(jié)流前,先傳輸 字符”ZERO WIDTH NO-BREAK SPACE” 。
這樣如果接收者收到FEFF ,就表明這個字節(jié)流是Big-Endian 的;如果收到FFFE ,就表明這個字節(jié)流是Little-Endian 的。因此字符”ZERO WIDTH NO-BREAK SPACE” 又被稱作BOM 。
UTF-8 不需要BOM 來表明字節(jié)順序,但可以用BOM 來表明編碼方式。字符”ZERO WIDTH NO-BREAK SPACE” 的UTF-8 編碼是EF BB BF 。所以如果接收者收到以EF BB BF 開頭的字節(jié)流,就知道這是UTF-8 編碼了。
?
記事本、 UltraEdit 和 VIM 對 BOM 支持情況如何 ?
答:記事本可以自動識別帶不帶BOM 的文本文件。
??? UltraEdit 如果在高級設(shè)置選擇了檢測UTF-8 ,則指出帶BOM 的utf-8 文件,否則亂碼。
??? Vim 支持bom 和不帶bom ,但是要在配置文件中設(shè)置:encoding=cp936 fileencodings=ucs-bom,utf-8,cp936 。
?
UNICODE 和 _UNICODE 的作用是什么 ?
答: _UNICODE 只是針對 CRT 標準庫的 unicode 定義 ,UNICODE 是針對 win32 api 的 unicode 定義。
這兩個宏的作用,就是在編譯時把相應(yīng)的標準接口替換成ansi 或unicode 版本。
如果定義了這兩個宏,vc 會編譯成unicode 版本。否則,編譯成ansi 版本。
?
?
如何編寫 unicode 程序 ?
答:通常有兩種方法:
1、 ? 代碼寫成ansi/unicode ,通過在工程中設(shè)置 UNICODE 和 _UNICODE 宏來控制是否支持 unicode 。
2、 ? 顯式定義unicdoe 變量和接口,顯式調(diào)用寬字符集標準庫接口和系統(tǒng)接口。
?
什么是 ANSI/Unicode 程序 ?
答:指同一份代碼可以編譯成ANSI 版本,也可以編譯成Unicode 版本,以便適應(yīng)不同的需求。
?
如何編寫 ANSI/Unicode 程序 ?
答:
1 、字符串變量或參數(shù)都定義成 TCHAR 、LPTSTR 或LPCTSTR 。
2 、調(diào)用標準庫或win32 的通用接口。
3、 ? 通過在工程中設(shè)置 UNICODE 和 _UNICODE 宏來控制生成 unicode 代碼或ansi 代碼。
4、 ? 對于常量字符串通過TEXT 宏來進行自動轉(zhuǎn)換。
?
如何使用 ansi/unicode 通用接口 ?
答:
1、 ? 對于標準庫,所有的ansi/unicode 通用接口都在tchar.h 中,每種常規(guī)的函數(shù)都有對應(yīng)的通用接口,比如:printf 對應(yīng)_tprintf 。
2、 ? 對于win32 api ,調(diào)用通用標準接口即可,因為大部分win32 api 都支持ansi/unicode 。
??? 比如調(diào)用 CreateWindow ,而不是顯示調(diào)用CreateWindowA 或CreateWindowW 。
3 、
?
Windows 對 unicode 的支持情況 ?
答: windows 98 部分支持 unicode ,windows NT/2k 以后版本在內(nèi)核中完全支持 unicode 。如果你的程序要在windows 98 和windows 2k 上同時運行,則最好寫成ansi/unicode ,在windows 98 上使用ansi 版本運行。
Windows CE 只支持Unicode ,只能開發(fā)純unicode 應(yīng)用程序。
?
VC 的資源是否 unicode , 對加載資源有什么影響 ?
答: 源編譯器對你的所有資源進行編譯時,輸出文件是資源的二進制文件。資源(字符串表、對話框模板和菜單等)中的字符串值總是寫作 Unicode 字符串。在 Windows 98 和 Windows 2000 下,如果應(yīng)用程序沒有定義 UNICODE 宏,那么系統(tǒng)就會進行內(nèi)部轉(zhuǎn)換。
?????? 如果在編譯源代碼模塊時沒有定義 UNICODE ,調(diào)用 LoadString 實際上就是調(diào)用 LoadStringA 函數(shù)。這時 LoadStringA 就從你的資源中讀。
?
如何判斷一段文本是否 unicode ?
答: 通過IsTextUnicode 可以來判斷一段文本是否為unicode 文本,它采用的是統(tǒng)計和定性的方法來判斷,因此有時會不準。
?
如何遍歷和操作 DBCS 字符串 ?
答: 在 crt 中,如_mbslen, 它可以用來操作多字節(jié)(既包括單字節(jié)也包括雙字節(jié))字符串。
???????????????????? 對DBCS 字符串進行操作的幫助函數(shù)
| 函數(shù) | 描述 |
| PTSTR CharNext(PCTSTR pszCurrentChar); | 返回字符串中的下一個字符的地址 |
| PTSTR CharPrev(PCTSTR pszStart,PCTSTR pszCurrentChar); | 返回字符串中的上一個字符的地址 |
| BOOL IsDBCSLeadByteTRUE(BYTE bTestChar); | 如果該字節(jié)是DBCS 字符的第一個字節(jié),則返回 |
如果是unicode 字符串,則只要移動指針就可以實現(xiàn)對字符串的遍歷。
?
常見的字符串類型有哪些 ?
答: 常見數(shù)據(jù)類型定義
| 數(shù)據(jù)類型 | 等價于 |
| LPTSTR | TCHAR * |
| LPCTSTR | const TCHAR * |
| wchar_t | unsigned short |
| WCHAR | wchar_t |
| LPWSTR | wchar_t * |
| LPCWSTR | const wchar_t * |
| LPSTR | char * |
| LPCSTR | const char * |
| OLECHAR | wchar_t |
| LPOLESTR | wchar_t * |
| LPCOLESTR | const wchar_t * |
?
_T(x) 、 __T(x) 、 _TEXT(x) 和 TEXT(x) 作用是什么?有什么區(qū)別?
答: _T(x) 、__T(x) 、_TEXT(x) 和TEXT(x) 作用相同,都是根據(jù)是否定義_UNICODE 宏來決定當(dāng)前字符或字符串x 轉(zhuǎn)換成寬字符串。
如果x 本身就是寬字符串則不做處理。
如果未定義_UNICODE ,則也對x 不做處理。
推薦使用TEXT(x) ,可讀性較好,也不用寫下劃線。
?
L 與 _T(x) 、 __T(x) 、 _TEXT(x) 、 TEXT(x) 有什么區(qū)別?
答:L 是明確告訴編譯器必須按照寬字符來處理。
??? 其他幾個是條件編譯的,由是否定義 UNICODE 宏決定。
?
如何操作 unicode 字符串?
答: 對Unicode 字符串進行操作的函數(shù)
| 函數(shù) | 描述 |
| lstrcat | 將一個字符串置于另一個字符串的結(jié)尾處 |
| lstrcmp | 對兩個字符串進行區(qū)分大小寫的比較 |
| lstrcmpi | 對兩個字符串進行不區(qū)分大小寫的比較 |
| lstrcpy | 將一個字符串拷貝到內(nèi)存中的另一個位置 |
| lstrlen | 返回字符串的長度(按字符數(shù)來計量) |
??? 這些函數(shù)是作為宏來實現(xiàn)的,這些宏既可以調(diào)用函數(shù)的Unicode 版本,也可以調(diào)用函數(shù)的ANSI 版本,這要根據(jù)編譯源代碼模塊時是否已經(jīng)定義了UNICODE 而定。例如,如果沒有定義UNICODE ,lstrcat 函數(shù)將擴展為lstrcatA 。如果定義了UNICODE ,lstrcat 將擴展為lstrcatW 。
?
如何讓 printf 支持 ansi/unicode ?
答:讓_printf 接口來替換printf 即可。
??? 示例代碼:
??? TCHAR lpBuffer[_MAX_FNAME];
??? _tprintf(TEXT(“%s/n”),lpBuffer);
?
在字符串操作函數(shù)中如何處理 ansi 和 unicode 字符串?
答: 如果在定義了_ UNICODE 的情況下編譯你的源代碼模塊,那么printf 函數(shù)家族便希望所有字符和字符串參數(shù)代表Unicode 字符和字符串。但是,如果在沒有定義_UNICODE 的情況下編譯你的源代碼模塊,printf 函數(shù)家族便希望傳遞給它的所有字符和字符串都是ANSI 字符和字符串。
char szA[100];???????????? //An ANSI string buffer
WCHAR szW[100];??????????? //A Unicode string buffer
?
//Normal sprintf:all strings are ANSI
sprintf(szA, "%s","ANSI Str");
?
//Converts Unicode string to ANSI
sprintf(szA,"%S",L"Unicode Str");
?
//Normal swprintf:all strings are Unicode
swprintf(szW,L"%s",L"Unicode Str");
?
//Converts ANSI string to Unicode
swprintf(szW,L"%S", "ANSI Str");
?
在 vc6 中為什么編譯 MFC unicode 程序會出錯,如何處理?
答: 在vc6 缺省安裝的MFC 不支持unicode ,必須在安裝時選擇支持多語言或全部安裝。否則,會出現(xiàn)LINK : fatal error LNK1104: cannot open file "mfc42ud.lib" 的錯誤。
?
什么情況下要用到資源 DLL ?
答:如果要想使UI 與邏輯分離,則制作資源DLL 是比較好的方法。
??? 好處有:
1、 ? UI 可以獨立于邏輯,獨立更新和升級。
2、 ? 如果要開發(fā)多語言應(yīng)用程序,不同語言的UI 只需要不同的資源DLL 即可,邏輯部分代碼不需要做任何改動。
?
如何制作 win32 資源 DLL ?
答: 因為win32 程序中代碼和資源沒有直接的聯(lián)系,因此可以先設(shè)計UI 及其他資源并生成DLL ,然后在exe 程序中動態(tài)加載資源DLL 。
?
??? 實現(xiàn)步驟 (以vc6 為例,一個簡單的文本編輯器示例):
1、 ? 創(chuàng)建一個win32 DLL 的工程,工程名稱為“NotePadRes ”,選擇“a simple DLL project ”,點擊finish 。
2、 ? 創(chuàng)建一個空的資源腳本文件,如MyNotePad.rc ,然后在ResourceView 中就會出現(xiàn)“MyNotePad resources ”目錄。
3、 ? 在ResourceView 中的“MyNotePad resources ”目錄上右鍵插入資源,設(shè)置資源ID 并編輯資源。在本示例中,我插入了圖標、菜單和快捷鍵資源,你也可以插入其他資源(如位圖、字符串表、對話框、鼠標等)。
??? 注意:在你編輯資源時,vc 編譯器會自動修改rc 文件,并且生成resource.h 文件。
4、 ? 編輯好資源后,編譯DLL ,輸出NotePadRes.dll 。
5、 ? 創(chuàng)建一個win32 application 的工程,工程名稱為“MyNotePad ”,選擇“a simple win32 application ”,點擊“完成”。
6、 ? 為了使用資源DLL 中的UI 資源,我們必須在創(chuàng)建窗口之前加載資源DLL ,因此在WinMain 的最開始處使用LoadLibrary 動態(tài)加載NotePadRes.dll 。
7、 ? 使用加載DLL 作為參數(shù),加載菜單、快捷鍵和圖標。注意:在注冊窗口類別時把菜單名稱設(shè)置為NULL ,而在創(chuàng)建窗口時把加載好的菜單句柄傳進去。這是windows 創(chuàng)建個性化菜單的一種手段,讓相同類別的窗口可以有不同的菜單。
8、 ? 拷貝NotePadRes 項目生成的resource.h 到MyNotePad 的代碼目錄,并且在MyNotePad.cpp 中引用該頭文件,這樣就可以使用NotePadRes 中的資源ID 。
9、 ? 在MyNotePad.cpp 中實現(xiàn)菜單和快捷鍵的響應(yīng)代碼,我這里只是為了演示如何分離代碼和資源,因此很多菜單的響應(yīng)代碼都沒有實現(xiàn)。
10、 ????????????? 編譯MyNotePad 。
11、 ????????????? 拷貝NotePadRes.dll 到MyNotePad 項目的輸出目錄。
12、 ????????????? 執(zhí)行MyNotePad.exe ,觀察演示效果。
?
?
如何制作 MFC 資源 DLL ?
答: MFC 程序是通過clw 文件來建立資源與代碼的聯(lián)系,clw 文件是在設(shè)計資源框架并通過ClassWizard 添加接口時產(chǎn)生,由vc 編譯器維護,手工編寫比較麻煩。
??? 另外,ClassWizad 不允許項目不包含資源文件。
??? 因為mfc 的代碼和資源關(guān)系比較密切,因此分離起來比win32 麻煩。
??? 一般MFC 程序資源和代碼分離的方法分為以下幾大步:1 、建立原型程序,完成所有UI 設(shè)計及相應(yīng)的接口框架。2 、編譯原型程序,并把rc 文件從原型中移出。3 、根據(jù)原型的rc 和resource.h 文件構(gòu)建資源DLL ,并在此基礎(chǔ)上進行修改。4 、在原型中載入資源DLL 。
?
實現(xiàn)步驟 (以vc6 為例,一個單文檔文本編輯器示例):
1 、創(chuàng)建一個MFC AppWizard(exe) 工程,工程名稱為“MyNotePad ”,選擇“Simple Document ”,語言選擇中文,點擊finish 。
2 、為了實現(xiàn)動態(tài)加載資源,則必須使用資源DLL 的句柄來取代MFC 缺省的資源句柄,MFC 缺省的資源是編譯在exe 中的。在CMyNotePadApp 中添加保護或私有變量m_hLangDLL 來保存資源DLL 句柄,在InitInstance 中加載資源DLL 并替換MFC 缺省資源句柄,在ExitInstance 中釋放資源DLL 。
注意: InitInstance 和ExitInstance 都是虛函數(shù),但是ExitInstance 在子類中沒有實現(xiàn),需要在CMyNotePadApp 定義虛函數(shù)并實現(xiàn)。
3 、為了說明是從資源鏈接庫中動態(tài)地獲取數(shù)據(jù)而不是從程序的執(zhí)行體中獲取,該程序從資源鏈接庫中獲取了一個圖標和一個字符串,并繪制在文檔顯示區(qū)域。代碼在CMyNotePadView::OnDraw 中實現(xiàn)。
??? 字符串ID 為IDS_WELCOME=300 ,內(nèi)容為”hello world” ,我們在后面的資源DLL 中改為其他內(nèi)容,以證實是從資源DLL 中加載的。
??? 圖標也在資源DLL 中做修改,比如在圖標中添加一個紅色的“中”字,以示區(qū)別于原來的圖標。
4 、編譯運行MyNotePad 工程。由于資源DLL 還未創(chuàng)建,運行時會出現(xiàn)" 無法裝載資源鏈接庫!" 錯誤提示。
5 、從MyNotePad 工程移出MyNotePad.rc 文件,并不從硬盤上刪除,因為后面構(gòu)建資源DLL 時要以此資源描述文件為基礎(chǔ)。
6 、創(chuàng)建一個MFC AppWizard(DLL) 的工程,工程名稱為“NotePadRes ”,選擇“Regular DLL using shared MFC DLL ”,點擊finish 。
7 、把NotePadRes.rc 和resource.h 從NotePadRes 工程中移出,并且從硬盤上刪除NotePadRes.rc 、resource.h 以及res 目錄下的所有文件。
8 、從MyNotePad 工程目錄中拷貝MyNotePad.rc 和resource.h 到NotePadRes 工程目錄下,并且把MyNotePad 工程的res 目錄下所有文件都拷貝到NotePadRes 工程的res 目錄下。
9 、把MyNotePad.rc 重命名為NotePadRes.rc 。根據(jù)個人喜好,此步可以不做,不影響正確性。
10 、在NotePadRes 工程中添加剛才拷貝的所有文件。
11 、修改字符串和圖標。
12 、在工程的setting->Resources 的預(yù)處理中刪除_AFXDLL ,使用戶的鏈接庫包含通用的MFC 資源。否則,應(yīng)用程序會從系統(tǒng)安裝的MFC 動態(tài)鏈接庫中收集通用的MFC 資源,應(yīng)用程序特定資源會被本地化。
13 、如果是制作其他語言版本的資源DLL ,還需要在setting->Resources 把語言改一下。
14 、在setting->link 的編譯選項中添加“/NOENTRY ”選項,表示輸出的為純資源DLL 。
15 、編譯NotePadRes ,設(shè)置輸出chinese.dll 資源DLL 。
16 、拷貝chinese.dll 到MyNotePad 的輸出目錄。
17 、運行MyNotePad.exe ,觀察演示效果。
?
兩種非 unicode 字符集如何轉(zhuǎn)換?
答: 兩種非unicode 字符集轉(zhuǎn)換方法,先把其中一種字符集轉(zhuǎn)換為unicode ,然后把unicode 字符集轉(zhuǎn)換為另外一種字符集。比如gb2312 與utf-8 轉(zhuǎn)換,先把gb2312 轉(zhuǎn)換為unicode ,然后把unicode 轉(zhuǎn)換為utf-8 。
?
如何轉(zhuǎn)換轉(zhuǎn)換 gb2312/gbk 為 unicode ?
答: int GbkTowchar(LPCSTR lpMultiByteStr,LPWSTR & lpWideCharStr,int & cchWideChar)
{
?? //revert utf8 string to wchar string
??? cchWideChar = ???????? ? MultiByteToWideChar(CP_ACP,0,lpMultiByteStr,strlen(lpMultiByteStr),NULL,0);
??? lpWideCharStr = new WCHAR[cchWideChar + 1];
?? memset(lpWideCharStr,0,sizeof(WCHAR) * (cchWideChar + 1));
?? MultiByteToWideChar(CP_ACP,0,lpMultiByteStr,strlen(lpMultiByteStr),lpWideCharStr,cchWideChar);
??
?? return cchWideChar;
}
?
// 使用轉(zhuǎn)換后pwStr 寬字符串
delete []lpWideCharStr;// 釋放寬字符串內(nèi)存
?
如何轉(zhuǎn)換轉(zhuǎn)換 unicode 為 utf-8 ?
答: int wcharToUTF8(LPCWSTR lpWideCharStr,LPSTR & lpMultiByteStr,int & cchMultiByte)
{
??? //revert wchar string to utf8 string
??? cchMultiByte = WideCharToMultiByte(CP_UTF8, 0, lpWideCharStr, sizeof(WCHAR) * wcslen(lpWideCharStr), lpMultiByteStr,0,NULL,NULL);// 獲取轉(zhuǎn)換成多字節(jié)字符串所需要的內(nèi)存
??? lpMultiByteStr = new char[cchMultiByte + 1];
??? memset(lpMultiByteStr,0,cchMultiByte + 1);
??? WideCharToMultiByte(CP_UTF8, 0, lpWideCharStr, sizeof(WCHAR) * wcslen(lpWideCharStr), lpMultiByteStr,cchMultiByte,NULL,NULL);
???
??? return cchMultiByte;
}
??? // 使用轉(zhuǎn)換后的字符串
??? Delete []lpMultiByteStr;// 釋放多字節(jié)字符串內(nèi)存
?
MySQL 字符集類型有哪些?
答: 類型:主機字符集、數(shù)據(jù)庫字符集、表字符集、列字符集、連接字符集。
關(guān)系:主機字符集 > 數(shù)據(jù)庫字符集 > 表字符集 > 列字符集,當(dāng)下一級字符集未指定時,以上級字符集為準。
?
?
MySQL 的各種字符集轉(zhuǎn)換關(guān)系是什么?
答:1 、發(fā)送請求。
??? 1) 客戶端發(fā)送請求到服務(wù)器端。
?? 2) 服務(wù)器端會把請求的數(shù)據(jù)從客戶端字符集(character_set_client) 轉(zhuǎn)成服務(wù)器連接字符集(character_set_connection) 。
?? 3) 然后服務(wù)器會檢測存儲區(qū)域(table ,column) 的字符集,然后把數(shù)據(jù)從連接字符集(character_set_connection) 轉(zhuǎn)為存儲區(qū)域(table ,column) 的字符集,然後再存儲或者查詢。
2 、返回請求。
? 1) 服務(wù)器將存儲區(qū)域(table ,column) 的字符集轉(zhuǎn)換成服務(wù)器連接字符集(character_set_connection) 。
? 2) 將服務(wù)器連接字符集(character_set_connection) 轉(zhuǎn)換成結(jié)果字符集(character_set_results) ,再發(fā)送到客戶端。
?
MySQL 字符集 Uincode 支持情況如何?
答: 1 、服務(wù)器端支持 UCS-2 Unicode ( UTF-16 )和 UTF-8 。
?????? 2 、客戶端只支持 UTF-8 。
?? ? 3 、在 4.1 之前的客戶端不支持 UTF-8 。
?
如何設(shè)置 MySQL 連接字符集?
答:有兩種方法:
1、 ? 在建立MySQL 連接前,設(shè)置MySQL 連接句柄屬性:
??? mysql_options(m_mysql_handle, MYSQL_SET_CHARSET_NAME, charset);
2、 ? 建立好MySQL 連接,在執(zhí)行所有SQL 語句前:
??? set names ‘ 字符集’;
?
國際化開發(fā)的協(xié)議字符串最好采用什么字符集?
答:最好使用UTF-8 ,原因是UTF-8 比較適合網(wǎng)絡(luò)傳輸,而且很方便的與其他字符集進行轉(zhuǎn)換。
?
國際化開發(fā)的數(shù)據(jù)庫最好采用什么字符集?
答:數(shù)據(jù)庫的字符集最好采用UTF-8 ,理由同上。
??? 另外,數(shù)據(jù)庫遷移時比較方便,不用考慮字符集轉(zhuǎn)換的問題,不會產(chǎn)生亂碼。
?
為什么 MySQL 數(shù)據(jù)庫已經(jīng)使用了 UTF-8 ,但是查詢出來的結(jié)果還是亂碼?
答:數(shù)據(jù)庫連接字符集和寫數(shù)據(jù)庫的字符集必須相同,否則就會出現(xiàn)無法轉(zhuǎn)換的問題,這是亂碼的根源。具體如何轉(zhuǎn)換,前面有專門說明。
?
國際化開發(fā)的日志文件和配置文件采用什么字符集比較好?
答:建議采用帶BOM 的UTF-8 編碼。
??? 理由如下:
1、 ? 可以支持多種語言。
2、 ? 沒有字節(jié)序的問題,unicode 有字節(jié)序的問題,需要另外處理。
3、 ? 大多數(shù)文本或配置文件解析工具都支持utf-8 。
?
Linux 服務(wù)器國際化開發(fā)采用什么方案比較好?
答:
方案一:
??? 1 、日志和配置文件都采用utf-8 存儲(帶BOM )。
2 、網(wǎng)絡(luò)協(xié)議字符串采用utf-8 字符集。
3、 ? 讀寫數(shù)據(jù)庫采用utf-8 字符集。
4、 ? 如果需要對字符串進行遍歷或修改,則把它轉(zhuǎn)換成unicode 處理,處理完成后再轉(zhuǎn)換成utf-8 。
5 、
此方案的好處是不用考慮字節(jié)序問題,缺點是對字符串進行處理不太方便,要做轉(zhuǎn)換。
?
方案二:
??? 所有的文件和網(wǎng)絡(luò)I/O 及數(shù)據(jù)庫都采用unicode ,文件存儲帶BOM ,不過網(wǎng)絡(luò)協(xié)議中的字符串要指明字節(jié)序(或都轉(zhuǎn)換成網(wǎng)絡(luò)字節(jié)序),這是它的不足之處。
??? 此方案的好處是所有字符串都可以直接處理,不用轉(zhuǎn)換。
??? 缺點是網(wǎng)絡(luò)協(xié)議中要指明字節(jié)序或轉(zhuǎn)換成網(wǎng)絡(luò)字節(jié)序。
?
?
記事本中如何輸入并顯示韓文?
答:打開控制面板-區(qū)域和語言選項-語言-詳細信息-添加-輸入語言選朝鮮語-確定。這個步驟就是讓你有了系統(tǒng)自帶的韓文輸入法,你按 alt+shift 或者 ctrl+shift 就可以把這個韓文輸入法調(diào)出來了。
然后,打開記事本-格式-字體,接著,字體( F) 那里選 BatangChe ,字符集那里選“韓文”,確定。好了你現(xiàn)在可以調(diào)出你的韓文輸入法在記事本上輸韓文了。但是當(dāng)你想保存的時候就有個提醒,如果你點“是”,保存了,再次打開的時候,那些韓文會亂碼。如果點“否”,就不能保存。那有沒有什么方法保存呢,請看第三步。
第三步,點記事本的文件-另存為,在編碼那里選 Unicode 或 utf-8 ,保存。現(xiàn)在你打開另存為的那個記事本,韓文沒變亂碼。成功了,你甚至可以把文件名都改為韓文呢。
?
?
如何處理中文、泰文和阿拉伯文的字符消息?
答:由于中文字符編碼一般都是gb2312 或GBK ,由一個或兩個輸入字符組成,但是只顯示一個字符。
??? 泰文和阿拉伯文都每輸入一個字符就顯示一個字符。
??? 處理辦法:
1、 ? 中文版本中,收到字符后判斷最高位是否為1 ,即是否大于127 ,證明是有兩個字符組成的漢字。否則,就是ASCII 碼字母或數(shù)字。
2、 ? 泰文或阿拉伯文版本,每收到一個wm_char 消息就顯示到屏幕上。
?
如何處理多語言界面字體顯示亂碼?
答:盡管把字符串變成了unicode ,但是有時仍然是顯示亂碼,原因是字體設(shè)置不正確。比如讓中文字體顯示泰文,或者反之,都不可能正常顯示的。
處理方法有兩種:
1、 ? 設(shè)置一種比較通用的字體,比如Arial Unicode MS ,此種方法一般用在支持換語言皮膚的應(yīng)用程序中。
2、 ? 根據(jù)不同語言設(shè)置不同的典型字體,比如對于簡體中文,設(shè)置仿宋體等肯定能夠正常顯示。
3 、方法一的字體不是非常美觀,而且對于沒有編入unicode 的字符無法顯示。
?
總結(jié)
以上是生活随笔為你收集整理的国际化开发技术FAQ的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux查看端口占用情况的命令
- 下一篇: 查看 android 设备号,获取And