請各位高手幫忙:利用delphi如何實現多國語言(50分)

  • 主题发起人 主题发起人 liyu
  • 开始时间 开始时间
L

liyu

Unregistered / Unconfirmed
GUEST, unregistred user!
我用ReSource DLL Wizard實現多國語言,但在程序中卻無法動態切換﹐須通過windows
的區域設定﹐重新啟動計算機后執行應用程序方可更改語言,請問各位有何高招:直接在
應用程式中切換語言!
 
在Delphi5中的Translation Manager设置好后,编译后不是加了个chs吗?应该是自动判断
来切换的。
也可以用下面的代码动态切换,但是下面的LoadNewResourceModel和ReinitializeForms是
Reint的单元的函数,该单元在Delphi$/Demos|Richedit目录下MEmhi$/tsourceModuley。
const French = (Sublang-French shl 10) or Lang-French;
...
if LoadNewResourceModule(French) <> 0 then
ReinitializeFormz;
 
一这样做>>
1. 例子:在窗体上放一个Label,一个PopMenu,采单为Chinese,English,当点击
Chinese时Label.Caption:='中文',当点击English时Label.Caption:='English',
2.请把这个单元文件加入:(此文件位于Delphi5的Demos下的RichEdit中)
unit ReInit;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms;

procedure ReinitializeForms;
function LoadNewResourceModule(Locale: LCID): Longint;

implementation

type
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;
ReloadInheritedComponent(Form, TForm);
end;
end;

end.

然后在主窗体文件中引用,主窗体单元文件为:
unit multiLang;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Menus, StdCtrls;

type
TForm1 = class(TForm)
Label1: TLabel;
MainMenu1: TMainMenu;
Chinese1: TMenuItem;
Chinese: TMenuItem;
English1: TMenuItem;
procedure ChineseClick(Sender: TObject);
procedure English1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
const
ENGLISHL = (SUBLANG_ENGLISH_US shl 10) or LANG_ENGLISH;
CHINESEL = (SUBLANG_CHINESE_SIMPLIFIED shl 10) or LANG_CHINESE;

implementation
uses ReInit;
{$R *.DFM}

procedure TForm1.ChineseClick(Sender: TObject);
begin
if LoadNewResourceModule(CHINESEL) <> 0 then
ReinitializeForms;
end;

procedure TForm1.English1Click(Sender: TObject);
begin
if LoadNewResourceModule(ENGLISHL) <> 0 then
ReinitializeForms;
end;

end.



3.利用向导Project—>Language—>New,将自动生成Dll(分别生成chs,eng两个
目录,你所要做的就是把窗体文件的Label的Caption分别翻译成'中文'和'English'.
(注意:State应为Translated)
4.保存工程组(为MultiLanguage.bpg)
5.最后全编译整个工程

 
多人接受答案了。
 
后退
顶部