原創|其它|編輯:郝浩|2010-06-02 10:51:20.000|閱讀 2419 次
概述:因為舊系統的緣故,有些用戶的系統DFM上設計時全是中文。在使用本多語言元件時,為了偷懶,編輯字典時把原語DDKey用中文來輸入,不按建議的方式用DDManager來置換為英文。碰到一個問題,就是程序在英文操作系統下運行,無論如何調整Charset,顯示都會是一堆問號。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
因為舊系統的緣故,有些用戶的系統DFM上設計時全是中文。在使用本多語言的組件時,為了偷懶,編輯字典時把原語DDKey用中文來輸入,不按建議的方式用DDManager來置換為英文。碰到一個問題,就是程序在英文操作系統下運行,無論如何調整Charset,顯示都會是一堆問號。
原因在于:delphi7的classes.pas中的TWriter對DFM的string按WideString轉成utf存儲,TReader讀取時獲得的是widestring,然后以string賦給多語言的組件,如TLale.Caption。即DFM本身的存儲是unicode的,這里不會有問題,但是因為多語言的組件本身不是unicode的,在把unicode給ansi是,發生了問題。
ansi直接賦值給unicode時,調用了system.pas的_WStrFromLStr,它按操作系統的codepage轉換。在設計時,因為你的操作系統是與你輸入法的codepage一致,所以沒有問題。
unicode直接賦值給ansi時,調用了system.pas的_LStrFromWStr,當你的程序在英文操作系統運行時,它實際上把DFM的unicode按英文來轉成了ansi,所以肯定出問題。
要解決這個問題,只有改變TReader的行為,即可以改變_LStrFromWStr函數,可以用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編譯時才有效。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:CSDN