Thursday, August 31, 2006

Big5 GB2312 convert 繁簡轉換

原作者: 不詳
加註 : 蕭沖

/*
蕭沖 於20051017注記
從下面的程式可以猜測出

1/ GB字集裡含有繁體字型與簡體字型
2/ GB裡的繁體字型部份轉為Unicode後便與Big5轉為Unicode後的值是一樣的
3/ 使用LCMapString函數可將GB裡的繁與簡字體做內碼映射轉換

由以上的三個重點演出如下的logical

1/ Big5 to GB 方法為:
Big5->Unicode (使用MultiByteToWideChar)
->GB繁字集(GBK)->GB簡字集(GB2312) (使用LCMapString)

2/ GB to Big5 方法為:
GB簡字集(GB2312)->GB繁字集(GBK) (使用LCMapString)
->Unicode->Big5 (使用WideCharToMultiByte)
*/
//1. 輸入Big5字符,返回Gb簡體字符
//---------------------------------------------------------------------------
//函數輸入Big5字符,返回Gb簡體字符
//---------------------------------------------------------------------------
AnsiString __fastcall Big2Gb(AnsiString sBig)
{
char* pszBig5=NULL; //Big5編碼的字符
wchar_t* wszUnicode=NULL; //Unicode編碼的字符
char* pszGbt=NULL; //Gb編碼的繁體字符
char* pszGbs=NULL; //Gb編碼的簡體字符
AnsiString sGb; //返回的字符串
int iLen=0; //需要轉換的字符數

pszBig5=sBig.c_str(); //讀入需要轉換的字符參數

//計算轉換的字符數
iLen=MultiByteToWideChar (950, 0, pszBig5, -1, NULL,0) ;
//給wszUnicode分配內存
wszUnicode=new wchar_t[iLen+1];
//轉換Big5碼到Unicode碼,使用了API函數MultiByteToWideChar
MultiByteToWideChar (950, 0, pszBig5, -1, wszUnicode,iLen);

//計算轉換的字符數
iLen=WideCharToMultiByte (936, 0, (PWSTR) wszUnicode, -1, NULL,0, NULL, NULL) ;
//給pszGbt分配內存
pszGbt=new char[iLen+1];
//給pszGbs分配內存
pszGbs=new char[iLen+1];
//轉換Unicode碼到Gb碼繁體,使用API函數WideCharToMultiByte
WideCharToMultiByte (936, 0, (PWSTR) wszUnicode, -1, pszGbt,iLen, NULL, NULL) ;

//轉換Gb碼繁體到Gb碼簡體,使用API函數LCMapString
LCMapString(0x0804,LCMAP_SIMPLIFIED_CHINESE, pszGbt, -1, pszGbs, iLen);

//返回Gb碼簡體字符
sGb=pszGbs;

//釋放內存
delete [] wszUnicode;
delete [] pszGbt;
delete [] pszGbs;

return sGb;
}

//2. 輸入Gb字符,返回Big5字符
//---------------------------------------------------------------------------
//函數輸入Gb字符,返回Big5字符
//---------------------------------------------------------------------------
AnsiString __fastcall Gb2Big(AnsiString sGb)
{
char* pszGbt=NULL; //Gb編碼的繁體字符
char* pszGbs=NULL; //Gb編碼的簡體字符
wchar_t* wszUnicode=NULL; //Unicode編碼的字符
char* pszBig5=NULL; //Big5編碼的字符
AnsiString sBig5; //返回的字符串
int iLen=0; //需要轉換的字符數


pszGbs=sGb.c_str(); //讀入需要轉換的字符參數

//計算轉換的字符數
iLen=MultiByteToWideChar (936, 0, pszGbs, -1, NULL,0) ;

//給pszGbt分配內存
pszGbt=new char[iLen*2+1];
//轉換Gb碼簡體到Gb碼繁體,使用API函數LCMapString
LCMapString(0x0804,LCMAP_TRADITIONAL_CHINESE, pszGbs, -1, pszGbt, iLen*2);

//給wszUnicode分配內存
wszUnicode=new wchar_t[iLen+1];
//轉換Gb碼到Unicode碼,使用了API函數MultiByteToWideChar
MultiByteToWideChar (936, 0, pszGbt, -1, wszUnicode,iLen);

//begin 蕭沖加改某些符號無法互轉,先手動取代!
const wchar_t wt = 0x2506;

for(int i=0;i <= iLen;i++)
{
if(wszUnicode[i]==wt)
{
wszUnicode[i]=0x2502;
}
}

//end 蕭沖修正

//計算轉換的字符數
iLen=WideCharToMultiByte (950, 0, (PWSTR) wszUnicode, -1, NULL,0, NULL, NULL) ;
//給pszBig5分配內存
pszBig5=new char[iLen+1];
//轉換Unicode碼到Big5碼,使用API函數WideCharToMultiByte
WideCharToMultiByte (950, 0, (PWSTR) wszUnicode, -1, pszBig5,iLen, NULL, NULL) ;

//返回Big5碼字符
sBig5=pszBig5;

//釋放內存
delete [] wszUnicode;
delete [] pszGbt;
delete [] pszBig5;

return sBig5;
}


void __fastcall TForm1::Button2Click(TObject *Sender)
{
this->Edit3->Text = Gb2Big(this->Edit1->Text);
}
//---------------------------------------------------------------------------

No comments: