線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:24097
推到 Plurk!
推到 Facebook!

文字轉碼程式

 
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-10-09 07:58:07 IP:211.76.xxx.xxx 未訂閱
寫這個工具主要是整理兩天來在網路上搜尋的結果, 最後還是在 KTOP 找到解答  感謝 > < src="http://delphi.ktop.com.tw/loadfile.php?TOPICID=17975290&CC=402010"> 由 黃國書 Kii Ali 的「技術_NT nls 問題」列表: "20000"="c_20000.nls" ;Taiwan 國家標準碼 CNS "20001"="c_20001.nls" ;Taiwan 公會碼 TCA "20002"="c_20002.nls" ;Taiwan 倚天碼 Eten "20003"="c_20003.nls" ;Taiwan IBM5550 "20004"="c_20004.nls" ;Taiwan 電信碼 Teletext "20005"="c_20005.nls" ;Taiwan 王安碼 Wang 應該包含大部分非BIG5的繁體中文,以我的 XP HomeEd. 預設只有裝 c_20000.nls 如果需要其他的 codepage 可以從 Windows 原版光碟中找,或是網路搜尋下載。 不想下載的就參考以下的原始碼吧 < class="code"> //--------------------------------------------------------------------------- // ◎ MS 定義支援的 codepage 及在 HTML 內的 CHARSET 代號對照表 // <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=windows-1251"> // http://msdn.microsoft.com/workshop/author/dhtml/reference/charsets/charset4.asp // ◎ 俄羅斯 Konstantin Kazarnovsky 對於 CP_nnnn.nls 與 C_nnnn.cls 檔的內容解析 // http://webcenter.ru/~kazarn/eng/nls.htm // ◎ 國人 黃國書 Kii Ali 所整理的「技術_NT nls 問題」 // http://ftp.isu.edu.tw/pub/CPatch/faq/tech/tech_nlsnt.txt // ◎ MS 說明如何自己加入 codepage // http://msdn.microsoft.com/library/en-us/vcce/htm/evc_appendices_1.asp // http://support.microsoft.com/default.aspx?scid=kb;EN-US;151701 // ◎ SANJYSAN 在 KTOP 所提供的「萬用轉碼函數」 // http://delphi.ktop.com.tw/topic.php?TOPIC_ID=55094 // <2004-10-09> 整理 by Lee, Dong-Liang // http://dllee.ktop.com.tw //--------------------------------------------------------------------------- #include #pragma hdrstop #include "CodePageUnit.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TStringList *CodePageListSupported; TStringList *CodePageList; CPINFOEX CodePageInfoEx; BOOL CALLBACK EnumCodePagesProc(LPTSTR lpCodePageString) // code page identifier string { UINT CodePage=String(lpCodePageString).ToIntDef(0); if(IsValidCodePage(CodePage)) // code page { GetCPInfoEx(CodePage,0,&CodePageInfoEx); CodePageList->AddObject(CodePageInfoEx.CodePageName,(TObject*)CodePage); CodePageListSupported->AddObject(CodePageInfoEx.CodePageName,(TObject*)CodePage); } else { CodePageList->AddObject(String(lpCodePageString)+" **Not Installed**", (TObject*)CodePage); } return true; } TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { CodePageList=new TStringList; CodePageListSupported=new TStringList; EnumSystemCodePages((CODEPAGE_ENUMPROC)EnumCodePagesProc, // callback function CP_SUPPORTED); // CP_INSTALLED: installed, CP_SUPPORTED: supported code pages Memo1->Lines->Add("This System Support All the following CodePage."); Memo1->Lines->Add("If the name of the CodePage is **Not Installed** means it is not installed."); Memo1->Lines->AddStrings(CodePageList); ComboBox1->Items->AddStrings(CodePageListSupported); ComboBox2->Items->AddStrings(CodePageListSupported); ComboBox1->ItemIndex=ComboBox1->Items->IndexOfObject((TObject*)950); ComboBox2->ItemIndex=ComboBox1->Items->IndexOfObject((TObject*)950); if(ComboBox1->ItemIndex<0)ComboBox1->ItemIndex=0; if(ComboBox2->ItemIndex<0)ComboBox2->ItemIndex=0; delete CodePageList; delete CodePageListSupported; } //--------------------------------------------------------------------------- // SANJYSAN http://delphi.ktop.com.tw/topic.php?TOPIC_ID=55094 // 萬用轉碼函數 #define UNICODE 0 void* __fastcall TForm1::CodeConvert(void *str, int code_from, int code_to, int MAXLENG) { PWSTR wszUnicode = NULL; //Unicode PSTR InStr = NULL; //from Code PSTR OutStr = NULL; //to Code int iLen = 0; //char length if (code_from!=UNICODE) // other to unicode { InStr = (char*)str; iLen = MultiByteToWideChar(code_from, 0, InStr, -1, NULL,0); wszUnicode = new wchar_t[MAXLENG+1]; MultiByteToWideChar(code_from, 0, InStr, -1, wszUnicode,iLen); if (code_to==UNICODE) return wszUnicode; } else wszUnicode = (PWSTR)str; //unicode to other iLen = WideCharToMultiByte(code_to, 0, wszUnicode, -1, NULL,0,NULL, NULL); OutStr = new char[MAXLENG+1]; WideCharToMultiByte(code_to, 0, wszUnicode, -1, OutStr,iLen,NULL, NULL); if (code_from!=UNICODE) delete [] wszUnicode; return OutStr; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { char *Output=NULL; char *Input=Memo1->Text.c_str(); Output=(char*)CodeConvert(Input, (int)ComboBox1->Items->Objects[ComboBox1->ItemIndex], (int)ComboBox2->Items->Objects[ComboBox2->ItemIndex], Memo1->Text.Length()*2); Memo1->Text=AnsiString(Output); delete Output; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { if(OpenDialog1->Execute()) Memo1->Lines->LoadFromFile(OpenDialog1->FileName); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button3Click(TObject *Sender) { if(SaveDialog1->Execute()) { Memo1->Lines->SaveToFile(SaveDialog1->FileName); ShowMessage("File Saved"); } } //--------------------------------------------------------------------------- 對了,忘了說明,我把 SANJYSAN 小改了一下,主要是字串長度, 原本的方式我轉出來都只有一行,後來火大,直接設一個比較大的數值 就 OK 了,而且發現設超大結果也是正常,所以,我才會直接以 2 倍 大小來處理。 另外,就是本來想用它應該也可以作簡繁轉換,沒想到 效果實在是不好... 不過,在繁轉繁的部分,應該算是不錯了。 吃軟也吃硬 dllee.ktop.com.tw StatPlus 系統資源監測器 @ SoftKing VMASK - ViewMove Automation Software Kernel 發表人 - dllee 於 2004/10/09 08:07:53
------
http://www.ViewMove.com
附加檔案:57431_CodePage.zip
conundrum
尊榮會員


發表:893
回覆:1272
積分:643
註冊:2004-01-06

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-10-09 13:38:47 IP:61.221.xxx.xxx 未訂閱
日語馬ㄟ通喔 哈哈 哈哈哈 一句話 真好 win2000上 執行 ok ok 試用過很多翻譯日文軟體 老是翻不準不然就是無法原貌呈現 除了 南極星老軟體也可以 原貌呈現日文 但在切換方式 令人髮指 殺咪 一點不通 議神 用於老東西的本文翻譯 只能說差了 這東西好EZ 哈哈 哈哈哈 使人抓狂
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-10-09 23:32:46 IP:211.76.xxx.xxx 未訂閱
感謝 conundrum 的測試,讓我發現,一定要先去安裝 conundrum 大大所介紹的 Unicode 補完計畫:    參照頁:http://leoboard.cpatch.org/cgi-bin/topic.cgi?forum=21&topic=405&show=0 網址:http://search.cpatch.org/download/patchutil/unicodeaton/unicodeaton_240.exe    裝完之後,使用此工具,就可以轉簡轉繁,不過轉出來的是 BIG5 中的簡體造字(這也是之前我自己測出來效果很差,但裝了 Unicode 補完計畫後效果就還可接受),而不是真的對應的繁體字,算是小缺陷。同樣,在裝了 Unicode 補完計畫後,就可以用 BIG5 中的日文造字來顯示日文,所以,也可以把日文轉用 BIG5 來顯示,但前題是要安裝 Unicode 補完計畫,或至少要裝中國海字集 for windows 才能顯示日文造字。    吃軟也吃硬 dllee.ktop.com.tw StatPlus 系統資源監測器 @ SoftKing VMASK - ViewMove Automation Software Kernel
------
http://www.ViewMove.com
SANJYSAN
一般會員


發表:5
回覆:10
積分:3
註冊:2002-05-28

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-10-11 14:10:47 IP:202.145.xxx.xxx 未訂閱
引言: 對了,忘了說明,我把 SANJYSAN 小改了一下,主要是字串長度, 原本的方式我轉出來都只有一行,後來火大,直接設一個比較大的數值 就 OK 了,而且發現設超大結果也是正常,所以,我才會直接以 2 倍 大小來處理。
因為原來的程式只是拿來轉一個字串而已,其長度來自: iLen = MultiByteToWideChar(code_from, 0, InStr, -1, NULL,0); 所以遇上0x00的字串結尾自然就停了。要轉整篇的話,MAXLENG是個方法,但最好還是把整個buffer(file)的大小傳進去比較好。
引言: 另外,就是本來想用它應該也可以作簡繁轉換,沒想到 效果實在是不好... 不過,在繁轉繁的部分,應該算是不錯了。
簡繁體和codepage沒有關係,那是字形的關係。big5碼裡也有big5碼的簡體字形,gb碼裡也有gb碼的繁體字形,所以要簡繁轉換的話得另外轉字形才行。當然一般是內碼字形一起轉就是了。 要轉簡繁字形的話,你得在前面內碼轉碼完畢後,再呼叫一個API: int LCMapString( LCID Locale, // locale identifier DWORD dwMapFlags, // mapping transformation type LPCTSTR lpSrcStr, // source string int cchSrc, // number of characters in source string LPTSTR lpDestStr, // destination buffer int cchDest // size of destination buffer ); MSDN上有對於這個API的說明,裡面有參數: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_5s2v.asp 當然這些參數得另外設定,基本上沒辦法用內碼直接判斷,因gb與big5都同時具有簡繁字形的關係。除非你強迫指定成轉big5就自動變繁體,gb就自動變簡體,但不建議這麼做。 又LCMapString的字型轉換還有個有趣的功能。看看MSDN上的參數說明: LCMAP_FULLWIDTH LCMAP_HALFWIDTH LCMAP_HIRAGANA LCMAP_KATAKANA LCMAP_LINGUISTIC_CASINGLCMAP_UPPERCASE LCMAP_LOWERCASE LCMAP_SIMPLIFIED_CHINESE LCMAP_SORTKEY LCMAP_TRADITIONAL_CHINESE LCMAP_UPPERCASE 這也就是說,字形轉換也可以轉日文,你可以把日文裡的平假片假,半形全形等自由轉換....
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-10-11 23:17:24 IP:211.76.xxx.xxx 未訂閱
感謝 SANJYSAN 的指教,說真的,沒有您的「萬用轉碼函數」 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=55094 也不可能有這篇...    而您提到的 LCMapString 除了 LCMAP_SIMPLIFIED_CHINESE Windows NT 4.0 and later: Maps traditional Chinese characters to simplified Chinese characters. LCMAP_TRADITIONAL_CHINESE Windows NT 4.0 and later: Maps simplified Chinese characters to traditional Chinese characters. 有比較明顯是簡繁轉換,其他的我實在是看不懂是由什麼轉到什麼... < > 有空再試試看吧... < > 吃軟也吃硬 dllee.ktop.com.tw StatPlus 系統資源監測器 @ SoftKing VMASK - ViewMove Automation Software Kernel
------
http://www.ViewMove.com
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-10-14 11:28:17 IP:220.139.xxx.xxx 未訂閱
已經試出來 SANJYSAN 所介紹的 LCMapString() 用 LCMAP_SIMPLIFIED_CHINESE 繁轉簡 用 LCMAP_TRADITIONAL_CHINESE 簡轉繁 在原 CodeConvert() return OutStr; 前加上 LCMapString() 及對應的參數即可。 當然,如果所選用的參數與 From To 的 CodePage 選用不同,那結果就還是亂碼一堆  如果正確選用,如: href="http://dllee.ktop.com.tw" target="blank">吃軟也吃硬 dllee.ktop.com.tw StatPlus 系統資源監測器 @ SoftKing VMASK - ViewMove Automation Software Kernel
------
http://www.ViewMove.com
SANJYSAN
一般會員


發表:5
回覆:10
積分:3
註冊:2002-05-28

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-10-14 17:28:17 IP:202.145.xxx.xxx 未訂閱
引言: 而您提到的 LCMapString 除了 LCMAP_SIMPLIFIED_CHINESE Windows NT 4.0 and later: Maps traditional Chinese characters to simplified Chinese characters. LCMAP_TRADITIONAL_CHINESE Windows NT 4.0 and later: Maps simplified Chinese characters to traditional Chinese characters. 有比較明顯是簡繁轉換,其他的我實在是看不懂是由什麼轉到什麼... < > 有空再試試看吧... < >
說明(個人判斷,實際上沒試過): LCMAP_FULLWIDTH (轉全形字) LCMAP_HALFWIDTH (轉半形字) 上面兩個可能用在日文(有分全形半形)或BIG5/GB的英文碼,譬如AA這樣的全半形字轉換。 LCMAP_HIRAGANA (轉成平假名,日文) LCMAP_KATAKANA (轉成片假名,日文) LCMAP_LINGUISTIC_CASINGLCMAP_UPPERCASE (不明) LCMAP_LOWERCASE (轉小寫,應該是英文) LCMAP_SIMPLIFIED_CHINESE (轉簡體) LCMAP_SORTKEY (不明) LCMAP_TRADITIONAL_CHINESE (轉繁體) LCMAP_UPPERCASE (轉大寫,應該是英文)
引言: 當然,如果所選用的參數與 From To 的 CodePage 選用不同,那結果就還是亂碼一堆 如果正確選用,如: From : 936 To : 950 再用 LCMapString() 及 LCMAP_TRADITIONAL_CHINESE 就可以完美的簡轉繁 From : 950 To : 936 再用 LCMapString() 及 LCMAP_SIMPLIFIED_CHINESE 就可以完美的繁轉簡
補充: unicode本身同時支援簡繁體,所以應該也可以用。 再者,gb碼用LCMAP_TRADITIONAL_CHINESE的話應該也可以轉成gb碼繁體。 big5的話就不太確定了。
muta
一般會員


發表:0
回覆:2
積分:0
註冊:2004-01-06

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-11-22 17:06:05 IP:220.130.xxx.xxx 未訂閱
感謝兩位先進,解決我一直想要簡單轉換簡體到繁體的困擾 不敢單獨發一篇文章佔篇幅,綜合兩位的程式及發文,小弟寫成BCB可方便使用的函數如下:     
 // GB to BIG5
AnsiString __fastcall GBToBig5(const AnsiString str)
{
        PWSTR wszUnicode = NULL; //Unicode
    PSTR InStr = NULL; //from Code
    PSTR OutStr = NULL; //to Code
    int iLen = 0; //char length        InStr = (char*)str.c_str();
    int InSize = str.Length();
    iLen = MultiByteToWideChar(936,0,InStr,InSize,NULL,0);
    wszUnicode = new wchar_t[iLen 1];
    MultiByteToWideChar(936,0,InStr,InSize,wszUnicode,iLen);            // 簡轉繁
    PWSTR wszUnicode2 = new wchar_t[iLen 1];
        LCMapStringW(0x0404, // Locale id of taiwan
                    LCMAP_TRADITIONAL_CHINESE,
                    wszUnicode, iLen,
                    wszUnicode2,iLen);        //unicode to other
    int uiLen = WideCharToMultiByte(950,0,wszUnicode2,iLen,NULL,0,NULL,NULL);
    OutStr = new char[uiLen 1];
    WideCharToMultiByte(950,0,wszUnicode2,iLen,OutStr,uiLen,NULL,NULL);            AnsiString ret = AnsiString(OutStr);
    delete [] OutStr ;
    delete [] wszUnicode;
    delete [] wszUnicode2 ;        return ret ;
}
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-11-22 21:06:06 IP:211.76.xxx.xxx 未訂閱
感謝 muta 的分享 < > 原來我的處理順序錯了 < > 我原本是把 LCMapString() 用在最後, 而您是用在中間... 改天再來試試有什麼不同。 再次感謝您的指教。 吃軟也吃硬 dllee.ktop.com.tw StatPlus 系統資源監測器 @ KTOP VMASK - ViewMove Automation Software Kernel
------
http://www.ViewMove.com
z858328y
一般會員


發表:7
回覆:9
積分:3
註冊:2006-08-29

發送簡訊給我
#10 引用回覆 回覆 發表時間:2008-01-25 13:50:43 IP:59.115.xxx.xxx 訂閱
真是太感謝大大了,解決了很久的多國語言的問題
系統時間:2024-04-27 11:12:30
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!