| 通过TfrmMain.LoginAction.Caption = 'xxx'这样的方式来定义资源的属性,然后通过RTTI即可轻松控制Delphi程序中的各种资源属性,不光是可以实现多语言界面,包括做权限控制等都是很方便的。 本例是以2002年在深圳为香港一家企业开发应用的时候编写的一个很小的Framework,实现多语言界面以及通过SDI模拟MDI,执行程序AesSys.tar.bz2提供下载,几年前写的东西,界面比较难看^_^。
窗体基类:通过TLocalRes获取资源,然后通过捕获自定义消息实现界面更新。
{ } { Lidaibin's Delphi Framework } { } { Copyright (c) 2001-2002 Lidaibin } { }
unit BaseFrm;
{$I LDBVer.inc}
interface
uses Windows, Messages, SysUtils{$IFDEF LDB_D6UP}, Variants, FWConsts, Classes, Graphics, Controls, Forms, Dialogs, LocalRes, TypInfo;
type { Please don't inherit from TBaseForm } TBaseForm = class(TForm) private { Private declarations } FOnMyRefresh: TNotifyEvent; FLocalRes: TLocalRes;
{ Receive WM_FORMREFRESHMSG message when the system parameters changed. } procedure FormRefresh(var Message: TMessage); message WM_FORMREFRESHMSG;
function GetVersion: Integer; procedure SetVersion(const Value: Integer); function GetVersionStr: String; procedure SetVersionStr(const Value: String); protected { protected declarations } procedure DoShow; override; public { Public declarations } constructor Create(AOwner: TComponent); override;
property Version: Integer read GetVersion write SetVersion; published { Published declarations } property LocalRes: TLocalRes read FLocalRes write FLocalRes; property VersionStr: String read GetVersionStr write SetVersionStr; property OnMyRefresh: TNotifyEvent read FOnMyRefresh write FOnMyRefresh; end;
implementation
{ TBaseForm }
constructor TBaseForm.Create(AOwner: TComponent); begin inherited Create(AOwner); end;
procedure TBaseForm.DoShow; begin inherited DoShow; if not (csDesigning in ComponentState) then SendMessage(Handle, WM_FORMREFRESHMSG, 0, 0); end;
procedure TBaseForm.FormRefresh(var Message: TMessage); var FClass: TClass; FResNames: TStrings; iResItem: Integer; FObject: TObject; sResName: String; vResValue: Variant; iPointPos: Integer; FPropInfo: PPropInfo; begin if not Assigned(LocalRes) then exit; FResNames := TStringList.Create; try FClass := Self.ClassType; while FClass <> nil do begin LocalRes.GetResNames(FClass.ClassName, FResNames); if FResNames.Count > 0 then for iResItem := 0 to FResNames.Count - 1 do begin sResName := FResNames[iResItem]; vResValue := LocalRes.Res[FClass.ClassName, sResName]; if Pos('.', sResName) <= 0 then begin if GetPropInfo(Self, SResName) <> nil then SetPropValue(Self, sResName, vResValue); end else begin iPointPos := Pos('.', sResName); FObject := FindComponent(Copy(sResName, 1, iPointPos - 1)); if FObject = nil then begin FPropInfo := GetPropInfo(Self, Copy(sResName, 1, iPointPos - 1)); if FPropInfo <> nil then if FPropInfo^.PropType^.Kind = tkClass then FObject := TObject(GetOrdProp(Self, FPropInfo)); end; Delete(sResName, 1, iPointPos); while FObject <> nil do begin if Pos('.', sResName) <= 0 then begin if GetPropInfo(FObject, sResName) <> nil then SetPropValue(FObject, sResName, vResValue); FObject := nil; end else begin iPointPos := Pos('.', sResName); FPropInfo := GetPropInfo(FObject, Copy(sResName, 1, iPointPos - 1)); if FPropInfo = nil then FObject := nil else begin if FPropInfo^.PropType^.Kind = tkClass then FObject := TObject(GetOrdProp(FObject, FPropInfo)) else FObject := nil; end; Delete(sResName, 1, iPointPos); end; end; end; end; FClass := FClass.ClassParent; end; finally FResNames.Clear; FResNames.Free; end;
if Assigned(FOnMyRefresh) then FOnMyRefresh(Self); end;
function TBaseForm.GetVersion: Integer; begin Result := LDBFrameworkVersion; end;
function TBaseForm.GetVersionStr: String; begin Result := LDBFrameworkVerStr; end;
procedure TBaseForm.SetVersion(const Value: Integer); begin
end;
procedure TBaseForm.SetVersionStr(const Value: String); begin
end;
end.
本来准备帖出TLocalRes的代码,但行数太长日志无法存储,可下载LocalRes.tar.bz2。 |