原作者: 不詳
加註 : 蕭沖

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

1/ GBK字集裡含有繁體字型與簡體字型
2/ GBK裡的繁體字型部份轉為Unicode後便與Big5轉為Unicode後的值是一樣的
3/ 使用LCMapString函數可將GBK裡的繁與簡字體做內碼映射轉換
4/ 常用之GB2312內碼其實是GBK字集裡的子集合(即GBK包含GB2312)
5/ GBK裡有繁體字,簡體字,日文漢字,韓國漢字等。GBK是「國(G)家標(B)準擴(K)展」的漢語拼音字首

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

1/ Big5 to GB 方法為:
Big5->Unicode (使用MultiByteToWideChar)
->GBK繁字範圍->GBK簡字範圍(相當於GB2312) (使用LCMapString)

2/ GB to Big5 方法為:
GBk簡字範圍(相當於GB2312)->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);
}
創作者介紹
創作者 aftcast 的頭像
aftcast

蕭沖的書房

aftcast 發表在 痞客邦 留言(1) 人氣()