多語言的元件 |
|
pcplayer99
尊榮會員 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
本人寫了一個多語言的元件。此元件讓你將寫好的程序裡的所有界面元素的Caption/hint屬性值寫到一個你指定的ini文件裡。也允許你從一個另外編輯好的INI文件讀入各個元素的Caption/Hint。這樣就可以在程序運行期間動態刷新界面顯示文字(比如更換檢體/繁體中文或者英文)。以下是全部代碼: unit LjnLanMan;
{----------------------------------------------------------------------------
界面更換文字的控件。考慮到更換文字後,文字的大小可能有變化,因此必須考慮界面上
的文字大小的排列。具體到 TLabel,如果是右對齊方式排列的,則必須設置其屬性:
AlignMent:=taRightJustfy,這樣當文字變長,它會向左邊延伸,而不是向右邊延伸導致右邊對不齊 另外,還需要有界面讓用戶調整字體的 CharSet和 Size。以出更好的顯示效果。
------------------------------------------------------------------------------}
interface uses
Windows, Messages, SysUtils, Forms,Classes,StdCtrls,ExtCtrls,ActnList,
Menus,IniFiles,TypInfo; type
TLjnLanMan = class(TComponent)
private
FFileName:String;
function GetFileName: String;
procedure SetFileName(const Value: String); protected
{ Protected declarations }
public
constructor Create(AOwner:TComponent);override;
procedure ReadHint(const AApplication:TApplication); //將界面上的提示字讀出來寫到文件中保存
procedure WriteHint(const AApplication:TApplication); //讀磁盤文件來刷新界面上的提示字;
published
property FileName:String read GetFileName write SetFileName;
end; //FILENAME屬性要給個默認值 procedure Register; implementation procedure Register;
begin
RegisterComponents('LJN', [TLjnLanMan]);
end; function HasProperty(AObject: TObject; const APropName: string): boolean;
begin //確認一個控件是否有某個屬性的函數。這個函數用了 TypInfo.pas裡的函數
Result := GetPropInfo(AObject.ClassInfo, APropName) <> nil;
end; { TLjnLanMan } constructor TLjnLanMan.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FFileName:='LJNLanguage';
// FApplication:=TApplication.Create(self);
end; function TLjnLanMan.GetFileName: String;
begin
Result:=FFileName;
end; procedure TLjnLanMan.SetFileName(const Value: String);
begin
FFileName:=Value;
end; procedure TLjnLanMan.ReadHint(const AApplication: TApplication);
var
i,j:Integer;
AList:TStringList;
PName,PValue:String; //屬性名;屬性值
begin
AList:=TStringList.Create;
try
for i:=0 to AApplication.ComponentCount-1 do
begin
if AApplication.Components[i] is TForm then
begin
With Application.Components[i] as TForm do
begin
Alist.Add('[' Name ']'); //把FORM的名字加在前面做一個INI的Section for j:=0 to ComponentCount-1 do
begin
if HasProperty(Components[j],'Caption') then
begin
AList.Add(Components[j].Name '_Caption=' GetStrProp(Components[j],'Caption'));
end; if HasProperty(Components[j],'Hint') then
begin
AList.Add(Components[j].Name '_Hint=' GetStrProp(Components[j],'Hint'));
end;
end;
end;
end;
AList.Add('');
end; //for i
AList.SaveToFile(FFileName);
finally
AList.Free;
end;
end; procedure TLjnLanMan.WriteHint(const AApplication: TApplication);
var
i,j:Integer;
myIni:TiniFile;
FormName:String; //屬性名;屬性值
begin
myIni:=TiniFile.Create(FFileName);
try
for i:=0 to AApplication.ComponentCount-1 do
begin
if AApplication.Components[i] is TForm then
begin
With AApplication.Components[i] as TForm do
begin
FormName:=Name;
for j:=0 to ComponentCount-1 do
begin //開始對這個form裡的控件逐個數
if HasProperty(Components[j],'Caption') then
SetStrProp(Components[j],'Caption',myIni.ReadString(FormName,Components[j].Name '_Caption','')); if HasProperty(Components[j],'Hint') then
SetStrProp(Components[j],'Hint',myIni.ReadString(FormName,Components[j].Name '_Hint',''));
end; //替換界面字符完成後,要刷新:
Update;
end;
end;
end;
finally
myIni.Free;
end;
end; end.
|
HarryZhang
一般會員 發表:19 回覆:25 積分:8 註冊:2003-01-03 發送簡訊給我 |
|
pcplayer99
尊榮會員 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
|
sos_admin
版主 發表:121 回覆:697 積分:768 註冊:2003-07-23 發送簡訊給我 |
|
pcplayer99
尊榮會員 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
引言: 把这个元件拖到你的Project的某个FORM上,给它的FileName属性一个值(保存文件),然后调用这个元件的WriteHint方法,就会将所有的Caption/Hint写到INI文件里去。 然后你编辑INI文件,把等号后的提示文字替换为你想要的文字。 然后,在你的Project的任何地方,调用此组件的ReadHint方法,就会自动刷新了。 pcplayer99 兄: 你的程式方法写反了,ReadHint好像是写,WriteHint是读哦 發表人 - >>< face="Verdana, Arial, Helvetica"> 是。我的程序,ReadHint是读FORM上的CAPTION/HINT,然后写到INI文件里。实际上这个方法只用一次,主要是为方便写好的程序直接生成INI文件,避免手动编辑INI文件的麻烦。 然后,用这个INI文件就可以再编辑其它语言的INI文件。在以后的使用里,只需要调用WriteHint,将INI文件的内容拿来写FORM里面的元件的CAPTION/HINT就好了。 当然,那个FileName属性,不是简单的文件名,必须是带路径的。比如,应该这样写: LjnLanMan1.FileName:=ExtractFilePath(Application.ExeName) 'ChineseBig5.ini'; |
mustapha.wang
資深會員 發表:89 回覆:409 積分:274 註冊:2002-03-13 發送簡訊給我 |
|
pcplayer99
尊榮會員 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
引言: src="http://delphi.ktop.com.tw/loadfile.php?TOPICID=10543105&CC=235795"> 久病成良医--多试 千人之诺诺,不如一士之谔谔--兼听请注意这段代码: if HasProperty(Components[j],'Caption') then begin AList.Add(Components[j].Name+'_Caption='+GetStrProp(Components[j],'Caption')); end; if HasProperty(Components[j],'Hint') then begin AList.Add(Components[j].Name+'_Hint='+GetStrProp(Components[j],'Hint')); end; 这里,我只写了 Caption/Hint两个Property. 如果你用到的元件有别的什么Property,你只需要在这里加上同样的代码,把里面的"Caption"替换为你需要的Property的名字即可。 |
wingchen
一般會員 發表:2 回覆:3 積分:1 註冊:2002-05-27 發送簡訊給我 |
|
pcplayer99
尊榮會員 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
|
azurecloud
中階會員 發表:52 回覆:108 積分:92 註冊:2003-09-04 發送簡訊給我 |
pcplayer99 大大您好:
非常感謝您所分享的這個元件,對我的幫助很大,我發現到一個現象,
那就是遍歷 form 時讀入的物件是 Radiogroup 時,讀不到裡面的 items
因為那是屬性值,而非物件;不像 mainmenu 物件,它的每一個 item 都
是一個獨立的物件,也都有自己的 Caption 屬性。
而當讀入的物件是 Radiogroup 時,我使用 GetStrProp(Components[j],'items')卻讀不到東西(是空白的),然我在 Unit 當中,查到 Radiogroup 物件是像這樣宣告的:
object RadioGroup1: TRadioGroup
Left = 16
Top = 16
Width = 185
Height = 105
Caption = '選擇執行條件'
Columns = 2
Items.Strings = (
'字元數為1 '
'字元數為2'
'字元數為3'
'字元數為4'
'字元數為5'
'其它')
TabOrder = 2
OnClick = RadioGroup1Click
end
那在程式中用這種語法:edit1.Text := radiogroup1.Items.Strings[0];
也可以把 Items 一個一個讀出來;但問題是 Strings[] 是 Items 的屬性
值,而 Items 也是屬性值 GetStrProp() 只能抓【物件】的屬性值,那不知
道有沒有什麼辦法可以抓【屬性】的屬性值呢?如果您知道的話,請教教我,
另外,再一次感謝您的分享。
|
pcplayer99
尊榮會員 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
引言: pcplayer99 大大您好: 非常感謝您所分享的這個元件,對我的幫助很大,我發現到一個現象, 那就是遍歷 form 時讀入的物件是 Radiogroup 時,讀不到裡面的 items 因為那是屬性值,而非物件;不像 mainmenu 物件,它的每一個 item 都 是一個獨立的物件,也都有自己的 Caption 屬性。 而當讀入的物件是 Radiogroup 時,我使用 GetStrProp(Components[j],'items')卻讀不到東西(是空白的),然我在 Unit 當中,查到 Radiogroup 物件是像這樣宣告的: object RadioGroup1: TRadioGroup Left = 16 Top = 16 Width = 185 Height = 105 Caption = '選擇執行條件' Columns = 2 Items.Strings = ( '字元數為1 ' '字元數為2' '字元數為3' '字元數為4' '字元數為5' '其它') TabOrder = 2 OnClick = RadioGroup1Click end 那在程式中用這種語法:edit1.Text := radiogroup1.Items.Strings[0]; 也可以把 Items 一個一個讀出來;但問題是 Strings[] 是 Items 的屬性 值,而 Items 也是屬性值 GetStrProp() 只能抓【物件】的屬性值,那不知 道有沒有什麼辦法可以抓【屬性】的屬性值呢?如果您知道的話,請教教我, 另外,再一次感謝您的分享。不好意思,我没研究过Items里的内容该如何处理。 |
azurecloud
中階會員 發表:52 回覆:108 積分:92 註冊:2003-09-04 發送簡訊給我 |
|
japhenchen
高階會員 發表:51 回覆:444 積分:184 註冊:2003-07-23 發送簡訊給我 |
這樣的題目我也曾寫過,不過我的做法比較蠢,我全弄在registry里,也是只支持caption跟hint,後來當我接觸了delphi內建的Multi Language Resource DLL之後,我就完全拋棄了另外自己寫多語系文件的念頭了,只需要簡單的用wizard產生對應語系檔,再自己進去編輯器里把詞語編輯一下語系CHARSET,字形FONTNAME還有改一下編碼,就可以簡單的支持多語系,何苦要自己累的半死去寫個殘缺不全的REG、INI啥的~ LIST的支援、LISTVIEW的支援、TREEVIEW的支援都弄的很完整,何以不用呢?
|
Diviner
初階會員 發表:36 回覆:112 積分:34 註冊:2002-03-13 發送簡訊給我 |
引言: 這樣的題目我也曾寫過,不過我的做法比較蠢,我全弄在registry里,也是只支持caption跟hint,後來當我接觸了delphi內建的Multi Language Resource DLL之後,我就完全拋棄了另外自己寫多語系文件的念頭了,只需要簡單的用wizard產生對應語系檔,再自己進去編輯器里把詞語編輯一下語系CHARSET,字形FONTNAME還有改一下編碼,就可以簡單的支持多語系,何苦要自己累的半死去寫個殘缺不全的REG、INI啥的~ LIST的支援、LISTVIEW的支援、TREEVIEW的支援都弄的很完整,何以不用呢?我正在找Multi Language Resource DLL的使用文件, 你可否說說其用法? 謝謝。 -- 小卜子
------
-- 小卜子 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |