全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2903
推到 Plurk!
推到 Facebook!

多語言的元件

 
pcplayer99
尊榮會員


發表:146
回覆:790
積分:632
註冊:2003-01-21

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-08-08 00:11:24 IP:219.133.xxx.xxx 未訂閱
本人寫了一個多語言的元件。此元件讓你將寫好的程序裡的所有界面元素的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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-08-08 10:54:09 IP:218.18.xxx.xxx 未訂閱
我将如何使它? Harry Zhang
------
Harry Zhang
pcplayer99
尊榮會員


發表:146
回覆:790
積分:632
註冊:2003-01-21

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-08-08 11:32:56 IP:219.133.xxx.xxx 未訂閱
引言: 我将如何使它? Harry Zhang
把这个元件拖到你的Project的某个FORM上,给它的FileName属性一个值(保存文件),然后调用这个元件的WriteHint方法,就会将所有的Caption/Hint写到INI文件里去。 然后你编辑INI文件,把等号后的提示文字替换为你想要的文字。 然后,在你的Project的任何地方,调用此组件的ReadHint方法,就会自动刷新了。
sos_admin
版主


發表:121
回覆:697
積分:768
註冊:2003-07-23

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-08-08 18:31:54 IP:61.155.xxx.xxx 未訂閱
把这个元件拖到你的Project的某个FORM上,给它的FileName属性一个值(保存文件),然后调用这个元件的WriteHint方法,就会将所有的Caption/Hint写到INI文件里去。    然后你编辑INI文件,把等号后的提示文字替换为你想要的文字。    然后,在你的Project的任何地方,调用此组件的ReadHint方法,就会自动刷新了。    pcplayer99 兄: 你的程式方法写反了,ReadHint好像是写,WriteHint是读 發表人 -
pcplayer99
尊榮會員


發表:146
回覆:790
積分:632
註冊:2003-01-21

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-08-09 01:46:55 IP:219.133.xxx.xxx 未訂閱
引言: 把这个元件拖到你的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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-08-11 09:40:13 IP:218.1.xxx.xxx 未訂閱
src="http://delphi.ktop.com.tw/loadfile.php?TOPICID=10543105&CC=235795"> 久病成良医--多试 千人之诺诺,不如一士之谔谔--兼听
------
江上何人初见月,江月何年初照人
pcplayer99
尊榮會員


發表:146
回覆:790
積分:632
註冊:2003-01-21

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-08-11 13:29:52 IP:61.144.xxx.xxx 未訂閱
引言: 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

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-08-13 18:44:19 IP:211.21.xxx.xxx 未訂閱
小弟有個問題請教: 假如是 list類別的資料如何修改此函式呢
pcplayer99
尊榮會員


發表:146
回覆:790
積分:632
註冊:2003-01-21

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-08-14 00:37:40 IP:218.18.xxx.xxx 未訂閱
引言: 小弟有個問題請教: 假如是 list類別的資料如何修改此函式呢
不好意思,我对LIST类别不熟悉。
azurecloud
中階會員


發表:52
回覆:108
積分:92
註冊:2003-09-04

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-09-07 21:09:11 IP:163.13.xxx.xxx 未訂閱
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

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-09-26 20:28:00 IP:218.17.xxx.xxx 未訂閱
引言: 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

發送簡訊給我
#12 引用回覆 回覆 發表時間:2003-09-28 21:16:38 IP:163.13.xxx.xxx 未訂閱
pcplayer 99 大大您好: 剛剛所說的問題,我在另一個討論區又問了一次(對您不好意思),已有先進為我解答,我列出網址讓您參考,再次謝謝您的分享。 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=37048
japhenchen
高階會員


發表:51
回覆:444
積分:184
註冊:2003-07-23

發送簡訊給我
#13 引用回覆 回覆 發表時間:2003-09-29 17:01:07 IP:211.96.xxx.xxx 未訂閱
這樣的題目我也曾寫過,不過我的做法比較蠢,我全弄在registry里,也是只支持caption跟hint,後來當我接觸了delphi內建的Multi Language Resource DLL之後,我就完全拋棄了另外自己寫多語系文件的念頭了,只需要簡單的用wizard產生對應語系檔,再自己進去編輯器里把詞語編輯一下語系CHARSET,字形FONTNAME還有改一下編碼,就可以簡單的支持多語系,何苦要自己累的半死去寫個殘缺不全的REG、INI啥的~ LIST的支援、LISTVIEW的支援、TREEVIEW的支援都弄的很完整,何以不用呢?
Diviner
初階會員


發表:36
回覆:112
積分:34
註冊:2002-03-13

發送簡訊給我
#14 引用回覆 回覆 發表時間:2004-08-10 17:14:34 IP:218.103.xxx.xxx 未訂閱
引言: 這樣的題目我也曾寫過,不過我的做法比較蠢,我全弄在registry里,也是只支持caption跟hint,後來當我接觸了delphi內建的Multi Language Resource DLL之後,我就完全拋棄了另外自己寫多語系文件的念頭了,只需要簡單的用wizard產生對應語系檔,再自己進去編輯器里把詞語編輯一下語系CHARSET,字形FONTNAME還有改一下編碼,就可以簡單的支持多語系,何苦要自己累的半死去寫個殘缺不全的REG、INI啥的~ LIST的支援、LISTVIEW的支援、TREEVIEW的支援都弄的很完整,何以不用呢?
我正在找Multi Language Resource DLL的使用文件, 你可否說說其用法? 謝謝。 -- 小卜子
------
--
小卜子
系統時間:2024-06-30 11:56:50
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!