原創(chuàng)|其它|編輯:郝浩|2010-06-02 10:51:20.000|閱讀 2419 次
概述:因為舊系統(tǒng)的緣故,有些用戶的系統(tǒng)DFM上設計時全是中文。在使用本多語言元件時,為了偷懶,編輯字典時把原語DDKey用中文來輸入,不按建議的方式用DDManager來置換為英文。碰到一個問題,就是程序在英文操作系統(tǒng)下運行,無論如何調(diào)整Charset,顯示都會是一堆問號。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
因為舊系統(tǒng)的緣故,有些用戶的系統(tǒng)DFM上設計時全是中文。在使用本多語言的組件時,為了偷懶,編輯字典時把原語DDKey用中文來輸入,不按建議的方式用DDManager來置換為英文。碰到一個問題,就是程序在英文操作系統(tǒng)下運行,無論如何調(diào)整Charset,顯示都會是一堆問號。
原因在于:delphi7的classes.pas中的TWriter對DFM的string按WideString轉(zhuǎn)成utf存儲,TReader讀取時獲得的是widestring,然后以string賦給多語言的組件,如TLale.Caption。即DFM本身的存儲是unicode的,這里不會有問題,但是因為多語言的組件本身不是unicode的,在把unicode給ansi是,發(fā)生了問題。
ansi直接賦值給unicode時,調(diào)用了system.pas的_WStrFromLStr,它按操作系統(tǒng)的codepage轉(zhuǎn)換。在設計時,因為你的操作系統(tǒng)是與你輸入法的codepage一致,所以沒有問題。
unicode直接賦值給ansi時,調(diào)用了system.pas的_LStrFromWStr,當你的程序在英文操作系統(tǒng)運行時,它實際上把DFM的unicode按英文來轉(zhuǎn)成了ansi,所以肯定出問題。
要解決這個問題,只有改變TReader的行為,即可以改變_LStrFromWStr函數(shù),可以用Hook的方法:
procedure MyLStrFromWStr(var Dest: AnsiString; const Source: WideString);
begin
Dest:=AcroMultiUtils.UnicodeDecode(Source,936);
end;
procedure MyLStrFromPWChar(var Dest: AnsiString; Source: PWideChar);
begin
Dest:=AcroMultiUtils.UnicodeDecode(Source,936);
end;
function MyLoadResString(ResStringRec: PResStringRec): string;
var
WS:WideString;
nLen:integer;
begin
if ResStringRec = nil then Exit;
if ResStringRec.Identifier < 64*1024 then
begin
Setlength(WS,4096);
nLen:=LoadStringW(FindResourceHInstance(ResStringRec.Module^),
ResStringRec.Identifier, PWideChar(WS), Length(WS));
SetLength(WS,nLen);
end
else
WS:= PWideChar(ResStringRec.Identifier);
Result:=AcroMultiUtils.UnicodeDecode(WS,936);
Result:=AcroMultiResource.ResourceStorage.GetDisplayValue(Result);
end;
begin
Application.Initialize;
TrapAPI.TrapStorage.Trap('rtl70.bpl','@System@@LStrFromWStr$qqrr17System@AnsiStringx17System@WideString',@MyLStrFromWStr);
TrapAPI.TrapStorage.Trap('rtl70.bpl','@System@@LStrFromPWChar$qqrr17System@AnsiStringpb',@MyLStrFromPWChar);
// TrapAPI.TrapStorage.Trap('rtl70.bpl','@System@LoadResString$qqrp20System@TResStringRec',@MyLoadResString);
TrapAPI.TrapStorage.Trap(@System.LoadResString,@MyLoadResString);
Application.CreateForm(TFormChineseDDKey, FormChineseDDKey);
Application.Run;
end.
以上方法只能是你的程序用Runtime Package編譯時才有效。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:CSDN