📄 multilangtranslator_clx.pas
字号:
unit MultilangTranslator;
(*
Author: Beat Straehl,
Kleiner, armasuisse
max@kleiner.com
Date: Mai 2003
juni 2005, resources, pascal analyzer, spain extension
juli 2006, Max Kleiner Framework FIS-HE
aug 2006 set Spain, more comps., resolve update problem
sep 2006 dynamic change in same form on instance
Jan 2007 small changes for Lazarus 0.9
April 2007 available for Kylix /Linux
locs= 366, 15.04.2007
Description:
Changing the language of strings(caption, hint, lines ...) of controls on
a form to a particular language. The Tag property of the controls has to
be set to values corresponding with the according resource strings.
Leaving a Tag value 0 means that the caption of the according control
isn't changed. Note that languages are distinguished by an offset of a
multiple of 1000. For instance german is 0, English has an offset of 1000,
French has one of 2000 and Italian's offset is 3000. If a Tag is set to
the value of a language resource string this multiple of 1000 has
to be omitted. An example:
Extract of a resource file *.rc:
1, "Inhalt"
1001, "Content"
2001, "Contenu"
3001, "Contenido"
4001, "Contenudo"
In this case to a Tag of a control which should show this text in the proper
language we have to assign the value 1. This can be done with the ObjectInspector.
Currently TMultilangSC supports the controls in :
procedure ChangeComponent(theComponent: TComponent;
const theLanguageOffset : integer);
This concept can be easily extended to other controls not listed
in procedure ChangeComponent.
Languages string are assigned to the particular captions after a forms
has been loaded from the resources. However its possible to use
the function GetResourceString at any time to load language dependend
strings from the language resource file. This is especially necessary
if TMultiLangSC is used independendly from a TForm.
Version: 1.4, Implementation with Comp or by runtime for Kylix
*)
interface
uses
SysUtils, Classes, LibC;
type
tLanguageChanging = procedure(Sender: TObject; theComponent: TComponent) of object;
tLanguageChanged = procedure(Sender: TObject) of object;
TMultilangSC = class(TComponent)
private
fLanguage: integer;
fOnLanguageChanging: tLanguageChanging;
fOnLanguageChanged: tLanguageChanged;
procedure SetLanguage(const Value: integer);
procedure ChangeLanguage(const languageOffset: integer);
procedure ChangeComponent(theComponent: TComponent;
const theLanguageOffset : integer);
function GetTopComponent: TComponent;
function GetResourceString(Ident: Integer): string;
{ Private declarations }
protected
//Loaded Initializes the component after the form file has been
//read into memory.
procedure Loaded; override;
public
constructor Create(AOwner: TComponent); override;
property LanguageOffset: integer read fLanguage write SetLanguage;
published
{ Published in ObjectInspector}
property OnLanguageChanging: tLanguageChanging read fOnLanguageChanging write fOnLanguageChanging;
property OnLanguageChanged: tLanguageChanged read fOnLanguageChanged write fOnLanguageChanged;
end;
PStrData = ^TStrData;
TStrData = record
Ident: Integer;
Str: string;
end;
procedure Register;
//var objMultilang: TMultilangSC;
implementation
Uses QForms, QStdCtrls, QComCtrls, QExtCtrls;
// START resource s tring wizard section
resourcestring
SSecLangDep_Language = 'Language';
SSecLangDep_SecureCenterXP = 'SecureCenterXP';
SSecLangDep_SOFTWAREGSTSecureCenterXP = '\SOFTWARE\GST\SecureCenterXP';
// END resource string wizard section
procedure Register;
begin
RegisterComponents(SSecLangDep_SecureCenterXP, [TMultilangSC]);
end;
{ TMultiLangSC}
constructor TMultiLangSC.Create(AOwner: TComponent);
// this creates an instance of TSecureLanguageDepenend and initializes
// its member variables.
begin
inherited;
fLanguage:= 0;
fOnLanguageChanging:= NIL;
fOnLanguageChanged:= NIL;
end;
procedure TMultilangSC.SetLanguage(const Value: integer);
// changes the language of a component tree (usually a form)
begin
fLanguage:= Value;
if not (csLoading in ComponentState) then
ChangeLanguage(fLanguage);
end;
function EnumStringModules(Instance: Longint; Data: Pointer): Boolean;
var
rs: TResStringRec;
Module: HModule;
begin
Module:= Instance;
rs.Module:= @Module;
with PStrData(Data)^ do begin
rs.Identifier:= Ident;
Str:= System.LoadResString(@rs);
Result:= Str ='';
//Result:= Str;
end;
end;
function TMultilangSC.GetResourceString(Ident: Integer): string;
var
StrData: TStrData;
begin
StrData.Ident:= Ident + LanguageOffset;
StrData.Str:= '';
EnumResourceModules(EnumStringModules, @StrData);
Result:= StrData.Str;
end;
function TMultilangSC.GetTopComponent: TComponent;
// searches upwards through a tree of components until its root is found
// or a component is of type TForm.
var x: TComponent;
begin
x:= Self;
Result:= x; // prevent compiler warning
while (Assigned(x)) and not (x is TForm) do begin
Result:= x;
x:= x.Owner;
end;
if Assigned(x) then
Result:= x;
end;
procedure TMultilangSC.ChangeLanguage(const languageOffset: integer);
// this method changes the language of a component tree, if we are not in design mode.
// after the whole tree of components has been change the event fOnLanguageChanged is
// called, if a value has been assigned to it. This give the client the opportunity
// to do his own language specific text assignments using GetResourceString.
begin
if not (csDesigning in ComponentState) then begin
ChangeComponent(GetTopComponent,languageOffset);
if Assigned(fOnLanguageChanged) then
fOnLanguageChanged(Self);
end;
end;
procedure TMultilangSC.ChangeComponent(theComponent: TComponent;
const theLanguageOffset: integer);
// this function changes the language of the components text fields recursively.
// for every component an event fOnLanguageChanging is called if a handler was
// assigned to it. This gives the client the opportunity to do additional language
// specific treatments on a component level. If for instance a component is a grid,
// the client can use this event to test whether this grid is the current processed
// component and if true he could use the opportunity to change column or
// row names using GetResourceString
var x : integer;
begin
if theComponent.ComponentCount > 0 then begin
for x:= 0 to theComponent.ComponentCount-1 do
ChangeComponent(theComponent.Components[x], theLanguageOffset);
end;
if theComponent.tag <> 0 then begin
if (theComponent is TForm) then
(theComponent as TForm).Caption:= GetResourceString(theComponent.tag)
else if (theComponent is TLabel) then
(theComponent as TLabel).Caption:= GetResourceString(theComponent.tag)
else if (theComponent is TCheckBox) then
(theComponent as TCheckBox).Caption:= GetResourceString(theComponent.tag)
else if (theComponent is TToolButton) then
(theComponent as TToolButton).Hint:= GetResourceString(theComponent.tag)
else if (theComponent is TButton) then
(theComponent as TButton).Caption:= GetResourceString(theComponent.tag)
else if (theComponent is TRadioButton) then
(theComponent as TRadioButton).Caption:= GetResourceString(theComponent.tag)
else if (theComponent is TGroupBox) then
(theComponent as TGroupBox).Caption:= GetResourceString(theComponent.tag)
else if (theComponent is TPanel) then
(theComponent as TPanel).Caption:= GetResourceString(theComponent.tag)
else if (theComponent is TTabSheet) then
(theComponent as TTabSheet).Caption:= GetResourceString(theComponent.tag)
else if (theComponent is TImage) then
(theComponent as TImage).Hint:= GetResourceString(theComponent.tag)
else if (theComponent is TRadioGroup) then
(theComponent as TRadioGroup).caption:=
GetResourceString(theComponent.tag)
else if (theComponent is TPaintBox) then
(theComponent as TPaintBox).Hint:= GetResourceString(theComponent.tag);
if Assigned(fOnLanguageChanging) then
fOnLanguageChanging(Self, theComponent);
end;
end;
procedure TMultilangSC.Loaded;
begin
inherited;
//LanguageOffset:= currentLanguage;
end;
initialization
//objMultilang:= TMultiLangSC.Create(NIL);
finalization
//objMultilang.Free;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -