我用languages--->add 添加了一种语言,但是系统自动帮我COPY了一份源码,
该不会是要我把所有的界面都手动改过来吧能不能给你例子

解决方案 »

  1.   

    我的系统使用ini文件来操作的;用Delphi自带的工具不太好用。
    方法如下:
    1).写一个函数判断操作系统语言类型;
    2).将界面上的文字与message保存到ini中;
    3).将ini文件中的字付给界面上。
    ...
    当然还有很多需要处理;关键是要写一个函数可以将界面元素的内容写入ini文件中,
    还有一个重要的函数是读取ini文件内容并付值。
      

  2.   

    具体的你可和我联系:
    MSN:[email protected]
      

  3.   

    一个和liufh520(搞IT真烦) 理论差不多的免费控件,可以方便的建立多国语言程序:http://www.tonixsoft.com/index.php?mmenu_id=4&smenu_id=0000
      

  4.   

    谢谢  tonylk(tony) ( ) 信誉:110  2003-09-12 16:27:00  得分:0 我学习了一下,觉得这样太麻烦了,我的是数据库应用程序,有几十个FORM,还有报表,要是这么写的话,我怕INI文件会过大。且不太实际
      

  5.   

    用Delphi实现多语言界面关键字:多语言界面,Delphi,国际化,本地化。随着Internet在全球的普及,一个软件开发者,开发出来的产品可以随意发布到全球各个角落,然而与此同时,开发出来的产品也面临着一个新的问题:如何实现各种不同的语言界面,甚至根据最终用户的操作系统的语言版本,自动更改语言界面?难道为每一个不同的语言编写一个不同的版本?不,完全没有必要。Delphi 5.0作为一个优秀的快速RAD开发工具,可以很容易地实现国际化支持,因为Delphi 5.0内置了对多语言界面的支持。一个程序,如果需要不同的语言版本,那么应该有一下几点需要注意的地方[]:1. 必须允许你的程序代码能够处理好各种语言字符串,例如如果要中文化,必须能够处理双字节。2. 你必须设计好你的程序界面,以便能够使你的程序界面元素有足够的空间显示语言文字信息。一般说来,在50个字节以内的英文单词所表达的意思,用其他的语言来描述的话,长度要超过50字节,但中文是一个例外。特别对于几个字节的英文单词,其他的语言的长度几乎百分之百要超过英文的长度!因此,必须在控件中留出足够的长度以便在更改语言之后,还能显示全部的语言文字信息。3. 你必须翻译所有的资源。本文将着重讨论如何用Delphi 5.0实现多语言的支持和切换,界面设计和上述要求不在本文讨论范围之内。要为程序添加语言支持,只要在Delphi主菜单项Project下面选择Languages?Add…即可。点击之后出现语言向导,读者按照向导进行操作即可。向导结束之后,会生成一个工程组文件(BPG),最后出现Translation Manager,软件开发者可以在这里翻译所有语言的所有资源,包括字体、位置、文字等等。说明一下:你可以随时随地用Project下面的Languages子菜单的功能来添加、删除、修改各种界面元素。做完上述工作之后,我们现在就差切换语言的代码了。为了切换语言,大家可以使用下面的一个单元[],单元中提供了两个函数,用来更换语言界面元素,其中LoadNewResourceModule是用来修改文字信息等等,ReinitializeForms用来重新刷新窗体和控件以保证同步。///文件名:MaltiLan.pasunit MaltiLan;interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms;procedure ReinitializeForms;function LoadNewResourceModule(Locale: LCID): Longint;implementationtypeTAsInheritedReader = class(TReader)Publicprocedure ReadPrefix(var Flags: TFilerFlags; var AChildPos: Integer); Override;end;procedure TAsInheritedReader.ReadPrefix(var Flags: TFilerFlags; var AChildPos: Integer);begininherited ReadPrefix(Flags, AChildPos);Include(Flags, ffInherited);end;function SetResourceHInstance(NewInstance: Longint): Longint;varCurModule: PLibModule;beginCurModule := LibModuleList;Result := 0;while CurModule <> nil dobeginif CurModule.Instance = HInstance thenbeginif CurModule.ResInstance <> CurModule.Instance thenFreeLibrary(CurModule.ResInstance);CurModule.ResInstance := NewInstance;Result := NewInstance;Exit;end;CurModule := CurModule.Next;end;end;function LoadNewResourceModule(Locale: LCID): Longint;varFileName: array[0..260] of char;P: PChar;LocaleName: array[0..4] of Char;NewInst: Longint;beginGetModuleFileName(HInstance, FileName, SizeOf(FileName));GetLocaleInfo(Locale, LOCALE_SABBREVLANGNAME, LocaleName, SizeOf(LocaleName));P := PChar(@FileName) + lstrlen(FileName);while (P^ <> '.') and (P <> @FileName) do Dec(P);NewInst := 0;Result := 0;if P <> @FileName thenbeginInc(P);if LocaleName[0] <> #0 thenbegin// Then look for a potential language/country translationlstrcpy(P, LocaleName);NewInst := LoadLibraryEx(FileName, 0, LOAD_LIBRARY_AS_DATAFILE);if NewInst = 0 thenbegin// Finally look for a language only translationLocaleName[2] := #0;lstrcpy(P, LocaleName);NewInst := LoadLibraryEx(FileName, 0, LOAD_LIBRARY_AS_DATAFILE);end;end;end;if NewInst <> 0 thenResult := SetResourceHInstance(NewInst)end;function InternalReloadComponentRes(const ResName: string; HInst: THandle; var Instance: TComponent): Boolean;varHRsrc: THandle;ResStream: TResourceStream;AsInheritedReader: TAsInheritedReader;begin { avoid possible EResNotFound exception }if HInst = 0 then HInst := HInstance;HRsrc := FindResource(HInst, PChar(ResName), RT_RCDATA);Result := HRsrc <> 0;if not Result then Exit;ResStream := TResourceStream.Create(HInst, ResName, RT_RCDATA);tryAsInheritedReader := TAsInheritedReader.Create(ResStream, 4096);tryInstance := AsInheritedReader.ReadRootComponent(Instance);finallyAsInheritedReader.Free;end;finallyResStream.Free;end;Result := True;end;function ReloadInheritedComponent(Instance: TComponent; RootAncestor: TClass): Boolean;function InitComponent(ClassType: TClass): Boolean;beginResult := False;if (ClassType = TComponent) or (ClassType = RootAncestor) then Exit;Result := InitComponent(ClassType.ClassParent);Result := InternalReloadComponentRes(ClassType.ClassName, FindResourceHInstance(FindClassHInstance(ClassType)), Instance) or Result;end;beginResult := InitComponent(Instance.ClassType);end;procedure ReinitializeForms;varCount: Integer;I: Integer;Form: TForm;beginCount := Screen.FormCount;for I := 0 to Count - 1 dobeginForm := Screen.Forms[I];ReloadInheritedComponent(Form, TForm);end;end;end.测试程序窗体单元文件如下:///单元文件名:unit1.pasunit Unit1;interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,Menus, MLanTool, ExtCtrls, StdCtrls;typeTForm1 = class(TForm)MainMenu1: TMainMenu;File1: TMenuItem;Exit1: TMenuItem;Language1: TMenuItem;Chese1: TMenuItem;English1: TMenuItem;Button1: TButton;Memo1: TMemo;ListBox1: TListBox;GroupBox1: TGroupBox;Panel1: TPanel;procedure Exit1Click(Sender: TObject);procedure Chese1Click(Sender: TObject);procedure English1Click(Sender: TObject);Private{ Private declarations }Public{ Public declarations }end;varForm1: TForm1;implementation{$R *.DFM}constENGLISH = (SUBLANG_ENGLISH_US shl 10) or LANG_ENGLISH;CHINESE = (SUBLANG_CHINESE_SIMPLIFIED shl 10) or LANG_CHINESE;procedure TForm1.Exit1Click(Sender: TObject);beginClose;end;procedure TForm1.Chese1Click(Sender: TObject);beginif LoadNewResourceModule(CHINESE) <> 0 thenReinitializeForms;end;procedure TForm1.English1Click(Sender: TObject);beginif LoadNewResourceModule(ENGLISH) <> 0 thenReinitializeForms;end;end.如果要自动切换语言,只要在FormCreate事件中添加如下代码即可:if LoadNewResourceModule(SysLocale.DefaultLCID) <> 0 thenReinitializeForms;说明一点:在程序完成的时候,你应该用Luanguages子菜单的Update Resources DLL功能更新所有的窗体和代码,然后用Build All Project编译所有的文件,这样才能保证你的程序正常运行。所有的源代码可以到<http://kingron.myetang.com/soft/MultiLan.rar>下载。后记:其实用INI文件也可以实现多语言界面的切换,好处是可以方便大家随时添加不同的语言文件,但是,对于一个大型的程序来说,用INI是不现实的。用INI实现语言界面的程序,大家可以到<http://kingron.myetang.com/soft/winupx.rar>下载源代码和测试程序。
     
      

  6.   

    用INI实现多语言界面的切换    
        
    对于INI文件的操作,我不多说了,仅仅就如何实现语言界面的切换做一个简单的说明:首先,必须把所有的INI语言文件的结构统一,这样,我们只要传入INI的文件名,就可以通用了,例如我们可以做一个过程SetLanguage(const FileName:string);,这样只要用SetLanguage('CN.INI')就可以了,第二个需要注意的地方,你应该可以让用户选择语言界面的文件,因此程序启动的时候,应该搜索程序目录下面的所有INI文件,当然,你可以在INI文件里面添加一些附加的东西,例如,判断是否是语言INI文件还是其他的配置文件,显示的文字等等~~~~~,如果你的程序中还使用了类似ShowMessage('File Saved!')之类的语句,那么也应该用变量代替!!!例如:ShowMessage(MSG_FILE_SAVED);然后读取INI的时候,一起读入MSG_FILE_SAVED,这样才能保证所有的信息全部变成相应的语言!如果对于这些嵌入程序的信息你怕一个个很麻烦的话, 可以用数组来做~~~~~~~~~:)。接下来就是翻译文字了,这个就~~~~~~~~免了吧?最重要的一步到了:切换语言!我以前的方法是自己写一个过程,用Lable1.Caption:=Ini.ReadString(....)之类的,$^*$#@&^@*(^@(^$@^,现在想起来,怎么这么弱?:(,真的很笨,嗯咳~~~~~~不许笑,:),这个方法有一个缺点就是如果你添加一个控件就^$#@&*^%@&*了~~~~~~~~~,所以必须找一个更好的方法!看看下面的函数就知道了:procedure SetLanguage(const FileName:string);使用这个方法对于大多数的情况已经够了,但是有一个不方便的地方是如果动态创建窗体或者控件的话,就不行了~~~~~:(,不过你可以根据你的需要,可以修改上面的过程,然后在每一个窗体的OnCreate中添加代码就可以了,例如你把上面的过程改成对单个窗体的,就可以了:)。如果还有考虑不到的控件,你自己添加好了~~:),对于一些小程序来说,下面的已经够了:{***************************************** 模块说明:利用切换INI切换语言函数** 作者:[email protected] *****************************************}{****************************************下面的编译指定表示是否导出成一个INI文件一般的情况下面,没有必要修改,但需要母本INI的时候,可以把注释去掉****************************************}{$IFNDEF INI_EXPORT}///{$DEFINE INI_EXPORT}{$ENDIF}{****************************************函数参数说明:FileName:Ini语言文件名msg:用于程序中的信息的保存数组IgnoreTagValue:需要忽略的组件的Tag值使用举例:varMsg:array of string;.....SetLanguage(ExtractFilePath(ParamStr(0))+'English.Ini',msg,$FF);那么函数会忽略所有Tag值为$FF的控件****************************************}procedure SetLanguage(const FileName: string; var msg: array of string; const IgnoreTagValue: byte = $FF);const///下面是一些常量TRANS_SECTION = 'Translations';MESSAGES = 'Messages';COMMON = 'Common';HINT = 'Hint';CAPTION = 'Caption';MSG_PRE = 'SS_Msg_';vari, j, k : integer;Component : TComponent;Control : TControl;Strings : TStrings;Id : string;OldCaption : pchar;L : integer;beginwith TIniFile.Create(FileName) dotry{$IFDEF INI_EXPORT}if Application.Title<>'' then WriteString(COMMON, 'Application.Title', Application.Title);WriteBool(COMMON, 'CheckValid', True);{$ELSE}if not ReadBool(COMMON, 'CheckValid', False) then exit; ///不是合法的语言文件Application.Title := ReadString(COMMON, 'Application.Title', Application.Title);{$ENDIF}for i := Low(msg) to High(msg) do ///读取非控件的一些语言元素{$IFDEF INI_EXPORT}if Msg[i]<>'' thenWriteString(MESSAGES, MSG_PRE + IntToStr(i), msg[i]);{$ELSE}msg[i] := ReadString(MESSAGES, MSG_PRE + IntToStr(i), msg[i]);{$ENDIF}for i := 0 to Screen.FormCount - 1 do ///遍历程序所有窗体begin{$IFDEF INI_EXPORT}if Screen.Forms[i].Caption<>'' thenWriteString(TRANS_SECTION, Screen.Forms[i].Name + '.' + CAPTION, Screen.Forms[i].Caption);if Screen.Forms[i].Hint<>'' thenWriteString(TRANS_SECTION, Screen.Forms[i].Name + '.' + HINT, Screen.Forms[i].Hint);{$ELSE}Screen.Forms[i].Caption := ReadString(TRANS_SECTION, Screen.Forms[i].Name + '.' + CAPTION, Screen.Forms[i].Caption);Screen.Forms[i].Hint := ReadString(TRANS_SECTION, Screen.Forms[i].Name + '.' + HINT, Screen.Forms[i].Hint);{$ENDIF}for j := 0 to Screen.Forms[i].ComponentCount - 1 do ///遍历窗体所有组件beginComponent := Screen.Forms[i].Components[j] as TComponent;if Component.Tag = IgnoreTagValue then Continue; ///需要忽略的控件Id := Screen.Forms[i].Name + '.' + Component.Name + '.';if Component is TControl then ///普通的控件如:TButton,TSpeedButton,TBitBtn,TCheckBox....beginControl := Component as TControl;/// 下面的代码是用来生成第一个INI文件使用的{$IFDEF INI_EXPORT}if Control.Hint<>'' thenWriteString(TRANS_SECTION, Id + HINT, Control.Hint);{$ELSE}Control.Hint := ReadString(TRANS_SECTION, Id + HINT, Control.Hint);{$ENDIF}if Control is TCustomEdit then Continue; ///忽略TMemo,TEdit之类的if (Component is TCustomListBox) or (Component is TCustomRadioGroup)or (Component is TCustomComboBox) then /// Listbox,RadioGroup,Combobox必须单独处理beginStrings := nil; ///本行用于忽略编译信息if Component is TCustomListBox then Strings := TCustomListBox(Component).Items;if Component is TCustomRadioGroup then Strings := TRadioGroup(Component).Items;if Component is TCustomComboBox then Strings := TCustomComboBox(Component).Items;for k := 0 to Strings.Count - 1 do ///遍历Items的每一项{$IFDEF INI_EXPORT}WriteString(TRANS_SECTION, ID + 'Items.' + IntToStr(k), Strings.Strings[k]);{$ELSE}Strings.Strings[k] := ReadString(TRANS_SECTION, ID + 'Items.' + IntToStr(k), Strings.Strings[k]);{$ENDIF}end;if Component is TCustomComboBox then Continue; ///Combobox还有一点儿问题,:-(L := Control.GetTextLen + 1;GetMem(OldCaption, L);Control.GetTextBuf(OldCaption, L);{$IFDEF INI_EXPORT}if StrPas(OldCaption)<>'' thenWriteString(TRANS_SECTION, Id + CAPTION, OldCaption);{$ELSE}Control.SetTextBuf(pchar(ReadString(TRANS_SECTION, Id + CAPTION, OldCaption)));{$ENDIF}FreeMem(OldCaption, L);continue;end;if Component is TMenuItem then /// 处理TMenuItembegin{$IFDEF INI_EXPORT}if (TMenuItem(Component).Caption<>'') and (TMenuItem(Component).Caption <>'-') thenWriteString(TRANS_SECTION, Id + CAPTION, TMenuItem(Component).Caption);if TMenuItem(Component).Hint<>'' thenWriteString(TRANS_SECTION, Id + HINT, TMenuItem(Component).Hint);{$ELSE}TMenuItem(Component).Caption := ReadString(TRANS_SECTION, ID + CAPTION, TMenuItem(Component).Caption);TMenuItem(Component).Hint := ReadString(TRANS_SECTION, ID + HINT, TMenuItem(Component).Hint);{$ENDIF}Continue;end;if Component is TCustomAction then /// 处理TActionbegin{$IFDEF INI_EXPORT}if TCustomAction(Component).Caption<>'' thenWriteString(TRANS_SECTION, Id + CAPTION, TCustomAction(Component).Caption);if TCustomAction(Component).Hint<>'' thenWriteString(TRANS_SECTION, Id + HINT, TCustomAction(Component).Hint);{$ELSE}TCustomAction(Component).Caption := ReadString(TRANS_SECTION, CAPTION, TCustomAction(Component).Caption);TCustomAction(Component).Hint := ReadString(TRANS_SECTION, ID + HINT, TCustomAction(Component).Hint);{$ENDIF}Continue;end;if Component is TOpenDialog then ///处理TOpenDialog,TSaveDialog,....begin{$IFDEF INI_EXPORT}if TOpenDialog(Component).Filter<>'' thenWriteString(TRANS_SECTION, Id + 'Filter', TOpenDialog(Component).Filter);if TOpenDialog(Component).Title<>'' thenWriteString(TRANS_SECTION, Id + 'Title', TOpenDialog(Component).Title);{$ELSE}TOpenDialog(Component).Filter := ReadString(TRANS_SECTION, ID + HINT, TOpenDialog(Component).Filter);TOpenDialog(Component).Title := ReadString(TRANS_SECTION, CAPTION, TOpenDialog(Component).Title);{$ENDIF}end;end;end;finallyFree;end;end;
     
       
      

  7.   

    采用MLangX组件,可以管理界面中的语言字串项目,在Cache中HASH方式查寻字串很快。
    下载 http://www.1bitsoft.com/downloads/mlxdemo1_1.zip
    可以与作者[email protected]联系 QQ 12821922
    正在征集测试用户,你可以得到一份正版的许可