呵呵,
http://delphi.mychangshu.com/dispdoc.asp?id=1075http://delphi.mychangshu.com/dispdoc.asp?id=545

解决方案 »

  1.   

    用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.pas
    unit MaltiLan;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms;procedure ReinitializeForms;
    function LoadNewResourceModule(Locale: LCID): Longint;implementationtype
      TAsInheritedReader = class(TReader)
      Public
        procedure ReadPrefix(var Flags: TFilerFlags; var AChildPos: Integer); Override;
      end;procedure TAsInheritedReader.ReadPrefix(var Flags: TFilerFlags; var AChildPos: Integer);
    begin
      inherited ReadPrefix(Flags, AChildPos);
      Include(Flags, ffInherited);
    end;function SetResourceHInstance(NewInstance: Longint): Longint;
    var
      CurModule: PLibModule;
    begin
      CurModule := LibModuleList;
      Result := 0;
      while CurModule <> nil do
      begin
        if CurModule.Instance = HInstance then
        begin
          if CurModule.ResInstance <> CurModule.Instance then
            FreeLibrary(CurModule.ResInstance);
          CurModule.ResInstance := NewInstance;
          Result := NewInstance;
          Exit;
        end;
        CurModule := CurModule.Next;
      end;
    end;function LoadNewResourceModule(Locale: LCID): Longint;
    var
      FileName: array[0..260] of char;
      P: PChar;
      LocaleName: array[0..4] of Char;
      NewInst: Longint;
    begin
      GetModuleFileName(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 then
      begin
        Inc(P);
        if LocaleName[0] <> #0 then
        begin
          // Then look for a potential language/country translation
          lstrcpy(P, LocaleName);
          NewInst := LoadLibraryEx(FileName, 0, LOAD_LIBRARY_AS_DATAFILE);
          if NewInst = 0 then
          begin
            // Finally look for a language only translation
            LocaleName[2] := #0;
            lstrcpy(P, LocaleName);
            NewInst := LoadLibraryEx(FileName, 0, LOAD_LIBRARY_AS_DATAFILE);
          end;
        end;
      end;
      if NewInst <> 0 then
        Result := SetResourceHInstance(NewInst)
    end;function InternalReloadComponentRes(const ResName: string; HInst: THandle; var Instance: TComponent): Boolean;
    var
      HRsrc: 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);
      try
        AsInheritedReader := TAsInheritedReader.Create(ResStream, 4096);
        try
          Instance := AsInheritedReader.ReadRootComponent(Instance);
        finally
          AsInheritedReader.Free;
        end;
      finally
        ResStream.Free;
      end;
      Result := True;
    end;function ReloadInheritedComponent(Instance: TComponent; RootAncestor: TClass): Boolean;  function InitComponent(ClassType: TClass): Boolean;
      begin
        Result := False;
        if (ClassType = TComponent) or (ClassType = RootAncestor) then Exit;
        Result := InitComponent(ClassType.ClassParent);
        Result := InternalReloadComponentRes(ClassType.ClassName, FindResourceHInstance(
          FindClassHInstance(ClassType)), Instance) or Result;
      end;begin
      Result := InitComponent(Instance.ClassType);
    end;procedure ReinitializeForms;
    var
      Count: Integer;
      I: Integer;
      Form: TForm;
    begin
      Count := Screen.FormCount;
      for I := 0 to Count - 1 do
      begin
        Form := Screen.Forms[I];
        ReloadInheritedComponent(Form, TForm);
      end;
    end;end.
    测试程序窗体单元文件如下:
    ///单元文件名:unit1.pas
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      Menus, MLanTool, ExtCtrls, StdCtrls;type
      TForm1 = 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;var
      Form1: TForm1;implementation{$R *.DFM}
    const
      ENGLISH = (SUBLANG_ENGLISH_US shl 10) or LANG_ENGLISH;
      CHINESE = (SUBLANG_CHINESE_SIMPLIFIED shl 10) or LANG_CHINESE;procedure TForm1.Exit1Click(Sender: TObject);
    begin
      Close;
    end;procedure TForm1.Chese1Click(Sender: TObject);
    begin
      if LoadNewResourceModule(CHINESE) <> 0 then
        ReinitializeForms;
    end;procedure TForm1.English1Click(Sender: TObject);
    begin
      if LoadNewResourceModule(ENGLISH) <> 0 then
        ReinitializeForms;
    end;end.
    如果要自动切换语言,只要在FormCreate事件中添加如下代码即可:
      if LoadNewResourceModule(SysLocale.DefaultLCID) <> 0 then
        ReinitializeForms;
    说明一点:在程序完成的时候,你应该用Luanguages子菜单的Update Resources DLL功能更新所有的窗体和代码,然后用Build All Project编译所有的文件,这样才能保证你的程序正常运行。
    所有的源代码可以到<http://kingron.myetang.com/soft/MultiLan.rar>下载。
    后记:其实用INI文件也可以实现多语言界面的切换,好处是可以方便大家随时添加不同的语言文件,但是,对于一个大型的程序来说,用INI是不现实的。用INI实现语言界面的程序,大家可以到<http://kingron.myetang.com/soft/winupx.rar>下载源代码和测试程序。
      

  2.   

    用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.pas
    unit MaltiLan;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms;procedure ReinitializeForms;
    function LoadNewResourceModule(Locale: LCID): Longint;implementationtype
      TAsInheritedReader = class(TReader)
      Public
        procedure ReadPrefix(var Flags: TFilerFlags; var AChildPos: Integer); Override;
      end;procedure TAsInheritedReader.ReadPrefix(var Flags: TFilerFlags; var AChildPos: Integer);
    begin
      inherited ReadPrefix(Flags, AChildPos);
      Include(Flags, ffInherited);
    end;function SetResourceHInstance(NewInstance: Longint): Longint;
    var
      CurModule: PLibModule;
    begin
      CurModule := LibModuleList;
      Result := 0;
      while CurModule <> nil do
      begin
        if CurModule.Instance = HInstance then
        begin
          if CurModule.ResInstance <> CurModule.Instance then
            FreeLibrary(CurModule.ResInstance);
          CurModule.ResInstance := NewInstance;
          Result := NewInstance;
          Exit;
        end;
        CurModule := CurModule.Next;
      end;
    end;function LoadNewResourceModule(Locale: LCID): Longint;
    var
      FileName: array[0..260] of char;
      P: PChar;
      LocaleName: array[0..4] of Char;
      NewInst: Longint;
    begin
      GetModuleFileName(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 then
      begin
        Inc(P);
        if LocaleName[0] <> #0 then
        begin
          // Then look for a potential language/country translation
          lstrcpy(P, LocaleName);
          NewInst := LoadLibraryEx(FileName, 0, LOAD_LIBRARY_AS_DATAFILE);
          if NewInst = 0 then
          begin
            // Finally look for a language only translation
            LocaleName[2] := #0;
            lstrcpy(P, LocaleName);
            NewInst := LoadLibraryEx(FileName, 0, LOAD_LIBRARY_AS_DATAFILE);
          end;
        end;
      end;
      if NewInst <> 0 then
        Result := SetResourceHInstance(NewInst)
    end;function InternalReloadComponentRes(const ResName: string; HInst: THandle; var Instance: TComponent): Boolean;
    var
      HRsrc: 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);
      try
        AsInheritedReader := TAsInheritedReader.Create(ResStream, 4096);
        try
          Instance := AsInheritedReader.ReadRootComponent(Instance);
        finally
          AsInheritedReader.Free;
        end;
      finally
        ResStream.Free;
      end;
      Result := True;
    end;function ReloadInheritedComponent(Instance: TComponent; RootAncestor: TClass): Boolean;  function InitComponent(ClassType: TClass): Boolean;
      begin
        Result := False;
        if (ClassType = TComponent) or (ClassType = RootAncestor) then Exit;
        Result := InitComponent(ClassType.ClassParent);
        Result := InternalReloadComponentRes(ClassType.ClassName, FindResourceHInstance(
          FindClassHInstance(ClassType)), Instance) or Result;
      end;begin
      Result := InitComponent(Instance.ClassType);
    end;procedure ReinitializeForms;
    var
      Count: Integer;
      I: Integer;
      Form: TForm;
    begin
      Count := Screen.FormCount;
      for I := 0 to Count - 1 do
      begin
        Form := Screen.Forms[I];
        ReloadInheritedComponent(Form, TForm);
      end;
    end;end.
    测试程序窗体单元文件如下:
    ///单元文件名:unit1.pas
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      Menus, MLanTool, ExtCtrls, StdCtrls;type
      TForm1 = 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;var
      Form1: TForm1;implementation{$R *.DFM}
    const
      ENGLISH = (SUBLANG_ENGLISH_US shl 10) or LANG_ENGLISH;
      CHINESE = (SUBLANG_CHINESE_SIMPLIFIED shl 10) or LANG_CHINESE;procedure TForm1.Exit1Click(Sender: TObject);
    begin
      Close;
    end;procedure TForm1.Chese1Click(Sender: TObject);
    begin
      if LoadNewResourceModule(CHINESE) <> 0 then
        ReinitializeForms;
    end;procedure TForm1.English1Click(Sender: TObject);
    begin
      if LoadNewResourceModule(ENGLISH) <> 0 then
        ReinitializeForms;
    end;end.
    如果要自动切换语言,只要在FormCreate事件中添加如下代码即可:
      if LoadNewResourceModule(SysLocale.DefaultLCID) <> 0 then
        ReinitializeForms;
    说明一点:在程序完成的时候,你应该用Luanguages子菜单的Update Resources DLL功能更新所有的窗体和代码,然后用Build All Project编译所有的文件,这样才能保证你的程序正常运行。
    所有的源代码可以到<http://kingron.myetang.com/soft/MultiLan.rar>下载。
    后记:其实用INI文件也可以实现多语言界面的切换,好处是可以方便大家随时添加不同的语言文件,但是,对于一个大型的程序来说,用INI是不现实的。用INI实现语言界面的程序,大家可以到<http://kingron.myetang.com/soft/winupx.rar>下载源代码和测试程序。
      

  3.   

    一篇资料:用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.pas
    unit MaltiLan;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms;procedure ReinitializeForms;
    function LoadNewResourceModule(Locale: LCID): Longint;implementationtype
      TAsInheritedReader = class(TReader)
      Public
        procedure ReadPrefix(var Flags: TFilerFlags; var AChildPos: Integer); Override;
      end;procedure TAsInheritedReader.ReadPrefix(var Flags: TFilerFlags; var AChildPos: Integer);
    begin
      inherited ReadPrefix(Flags, AChildPos);
      Include(Flags, ffInherited);
    end;function SetResourceHInstance(NewInstance: Longint): Longint;
    var
      CurModule: PLibModule;
    begin
      CurModule := LibModuleList;
      Result := 0;
      while CurModule <> nil do
      begin
        if CurModule.Instance = HInstance then
        begin
          if CurModule.ResInstance <> CurModule.Instance then
            FreeLibrary(CurModule.ResInstance);
          CurModule.ResInstance := NewInstance;
          Result := NewInstance;
          Exit;
        end;
        CurModule := CurModule.Next;
      end;
    end;function LoadNewResourceModule(Locale: LCID): Longint;
    var
      FileName: array[0..260] of char;
      P: PChar;
      LocaleName: array[0..4] of Char;
      NewInst: Longint;
    begin
      GetModuleFileName(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 then
      begin
        Inc(P);
        if LocaleName[0] <> #0 then
        begin
          // Then look for a potential language/country translation
          lstrcpy(P, LocaleName);
          NewInst := LoadLibraryEx(FileName, 0, LOAD_LIBRARY_AS_DATAFILE);
          if NewInst = 0 then
          begin
            // Finally look for a language only translation
            LocaleName[2] := #0;
            lstrcpy(P, LocaleName);
            NewInst := LoadLibraryEx(FileName, 0, LOAD_LIBRARY_AS_DATAFILE);
          end;
        end;
      end;
      if NewInst <> 0 then
        Result := SetResourceHInstance(NewInst)
    end;function InternalReloadComponentRes(const ResName: string; HInst: THandle; var Instance: TComponent): Boolean;
    var
      HRsrc: 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);
      try
        AsInheritedReader := TAsInheritedReader.Create(ResStream, 4096);
        try
          Instance := AsInheritedReader.ReadRootComponent(Instance);
        finally
          AsInheritedReader.Free;
        end;
      finally
        ResStream.Free;
      end;
      Result := True;
    end;function ReloadInheritedComponent(Instance: TComponent; RootAncestor: TClass): Boolean;  function InitComponent(ClassType: TClass): Boolean;
      begin
        Result := False;
        if (ClassType = TComponent) or (ClassType = RootAncestor) then Exit;
        Result := InitComponent(ClassType.ClassParent);
        Result := InternalReloadComponentRes(ClassType.ClassName, FindResourceHInstance(
          FindClassHInstance(ClassType)), Instance) or Result;
      end;begin
      Result := InitComponent(Instance.ClassType);
    end;procedure ReinitializeForms;
    var
      Count: Integer;
      I: Integer;
      Form: TForm;
    begin
      Count := Screen.FormCount;
      for I := 0 to Count - 1 do
      begin
        Form := Screen.Forms[I];
        ReloadInheritedComponent(Form, TForm);
      end;
    end;end.
    测试程序窗体单元文件如下:
    ///单元文件名:unit1.pas
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      Menus, MLanTool, ExtCtrls, StdCtrls;type
      TForm1 = 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;var
      Form1: TForm1;implementation{$R *.DFM}
    const
      ENGLISH = (SUBLANG_ENGLISH_US shl 10) or LANG_ENGLISH;
      CHINESE = (SUBLANG_CHINESE_SIMPLIFIED shl 10) or LANG_CHINESE;procedure TForm1.Exit1Click(Sender: TObject);
    begin
      Close;
    end;procedure TForm1.Chese1Click(Sender: TObject);
    begin
      if LoadNewResourceModule(CHINESE) <> 0 then
        ReinitializeForms;
    end;procedure TForm1.English1Click(Sender: TObject);
    begin
      if LoadNewResourceModule(ENGLISH) <> 0 then
        ReinitializeForms;
    end;end.
    如果要自动切换语言,只要在FormCreate事件中添加如下代码即可:
      if LoadNewResourceModule(SysLocale.DefaultLCID) <> 0 then
        ReinitializeForms;
    说明一点:在程序完成的时候,你应该用Luanguages子菜单的Update Resources DLL功能更新所有的窗体和代码,然后用Build All Project编译所有的文件,这样才能保证你的程序正常运行。
    所有的源代码可以到<http://kingron.myetang.com/soft/MultiLan.rar>下载。
    后记:其实用INI文件也可以实现多语言界面的切换,好处是可以方便大家随时添加不同的语言文件,但是,对于一个大型的程序来说,用INI是不现实的。用INI实现语言界面的程序,大家可以到<http://kingron.myetang.com/soft/winupx.rar>下载源代码和测试程序。