www.pudn.com > HgzVip1.2_code.rar > LangMgr.pas


unit LangMgr; 
 
(* ======================================================== *) 
(* TLangMgr                                                 *) 
(* ======================================================== *) 
(*   globally manager the multi language, any class want to *) 
(* support multi language should implement the interface    *) 
(* ILangIntf, and then reference the TLangObject or         *) 
(* TLangForm.                                               *) 
(*   tony                                                   *) 
(*   2003.03.17                                             *) 
(* ======================================================== *) 
 
interface 
 
uses 
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, ComCtrls, DBGrids, IniFiles, TypInfo, Registry; 
 
type 
  ILangIntf = interface 
    procedure DoChangeLanguage(); 
    function Translate(Ident:String;Default:String):String;overload; 
    function Translate(Ident:String;Default:String;const Args:array of const):String;overload; 
  end; 
 
  PLangItem = ^TLangItem; 
  TLangItem = record 
    LangName:String; 
    FileName:String; 
  end; 
 
  TLangMgr = class(TObject) 
  private 
    ALangIndex:Integer; 
    ALangList:TList; 
    ALangObjList:TList; 
    function GetLangName(FileName:String):String; 
    function IsLangFile(FileName:String):Boolean; 
    function GetDefaultLangExt():String; 
    function GetSavedLangExt():String; 
    procedure SaveLangExt(Ext:String); 
    procedure InitLangList(); 
  public 
    constructor Create(); 
    destructor Destroy();override; 
    procedure GetLanguageList(LangList:TStringList;var LangIndex:Integer); 
    procedure AddLangObj(LangObj:ILangIntf); 
    procedure RemoveLangObj(LangObj:ILangIntf); 
    procedure ChangeLanguage(LangIndex:Integer); 
    function GetActiveLangFileName():String; 
  end; 
 
var 
  ALangMgr:TLangMgr; 
 
implementation 
 
const 
  RegistryPath = '\Software\Tony Workshop\LangManager'; 
 
{ TLangMgr } 
 
//get the language's name from ini file 
//2003.03.17 
function TLangMgr.GetLangName(FileName:String):String; 
var 
  Ini:TIniFile; 
begin 
  Ini:=TIniFile.Create(FileName); 
  try 
    Result:=Ini.ReadString('General','Language',''); 
  finally 
    Ini.Free; 
  end; 
end; 
 
//test if file is a valid language file 
//2003.03.17 
function TLangMgr.IsLangFile(FileName:String):Boolean; 
var 
  Ini:TIniFile; 
begin 
  Ini:=TIniFile.Create(FileName); 
  try 
    Result:=Ini.SectionExists('General'); 
  finally 
    Ini.Free; 
  end; 
end; 
 
//get the system's default language's name, return it as a file ext name 
//2003.03.17 
function TLangMgr.GetDefaultLangExt():String; 
var 
  LocaleName: array[0..4] of Char; 
begin 
  GetLocaleInfo(SysLocale.DefaultLCID,LOCALE_SABBREVLANGNAME,LocaleName,SizeOf(LocaleName)); 
  Result:='.'+LocaleName; 
end; 
 
//get the last saved language file's ext name 
//2003.03.17 
function TLangMgr.GetSavedLangExt():String; 
var 
  Reg:TRegistry; 
begin 
  Reg:=TRegistry.Create(); 
  try 
    Reg.RootKey:=HKEY_CURRENT_USER; 
    if not Reg.OpenKey(RegistryPath,false) then begin 
      exit; 
    end; 
    if Reg.ValueExists(ExtractFileName(Application.ExeName)) then begin 
      Result:=Reg.ReadString(ExtractFileName(Application.ExeName)); 
    end; 
  finally 
    Reg.Free; 
  end; 
end; 
 
//save the current language file's ext to registry 
//2003.03.17 
procedure TLangMgr.SaveLangExt(Ext:String); 
var 
  Reg:TRegistry; 
begin 
  Reg:=TRegistry.Create(); 
  try 
    Reg.RootKey:=HKEY_CURRENT_USER; 
    if not Reg.OpenKey(RegistryPath,true) then begin 
      exit; 
    end; 
    Reg.WriteString(ExtractFileName(Application.ExeName),Ext); 
    Reg.CloseKey; 
  finally 
    Reg.Free; 
  end; 
end; 
 
//search the application path for language file, store them in the list 
//2003.03.17 
procedure TLangMgr.InitLangList(); 
var 
  Sr:TSearchRec; 
  FileName:string; 
  LangItem:PLangItem; 
begin 
  ALangList.Clear; 
  if FindFirst(ChangeFileExt(Application.ExeName,'.*'),faAnyFile,Sr) = 0 then begin 
    repeat 
      FileName:=ExtractFilePath(Application.ExeName)+Sr.Name; 
      if IsLangFile(FileName) then begin 
        new(LangItem); 
        LangItem^.LangName:=GetLangName(FileName); 
        LangItem^.FileName:=FileName; 
        ALangList.Add(LangItem); 
      end; 
    until FindNext(Sr) <> 0; 
    FindClose(Sr); 
  end; 
end; 
 
//constructor 
//2003.03.17 
constructor TLangMgr.Create(); 
var 
  I:Integer; 
  LangItem:PLangItem; 
  DefaultExt:String; 
begin 
  inherited; 
  ALangList:=TList.Create(); 
  ALangObjList:=TList.Create(); 
  InitLangList(); 
  DefaultExt:=GetSavedLangExt(); 
  if Length(DefaultExt)=0 then 
    DefaultExt:=GetDefaultLangExt(); 
  ALangIndex:=-1; 
  for i:=0 to ALangList.Count-1 do begin 
    LangItem:=ALangList.Items[i]; 
    if CompareText(ExtractFileExt(LangItem^.FileName),DefaultExt)=0 then begin 
      ALangIndex:=i; 
      exit; 
    end; 
  end; 
end; 
 
//destructor 
//2003.03.17 
destructor TLangMgr.Destroy(); 
var 
  I:Integer; 
  LangItem:PLangItem; 
begin 
  for I:=0 to ALangList.Count-1 do begin 
    LangItem:=ALangList.Items[i]; 
    dispose(LangItem); 
  end; 
  ALangList.Free; 
  if ALangObjList.Count>0 then begin 
    raise Exception.Create('unsafe free of Language Manager!'); 
  end; 
  ALangObjList.Free; 
  inherited; 
end; 
 
//return the list of language file name, and the active language index 
//2003.03.17 
procedure TLangMgr.GetLanguageList(LangList:TStringList;var LangIndex:Integer); 
var 
  I:Integer; 
  LangItem:PLangItem; 
begin 
  LangIndex:=-1; 
  LangList.BeginUpdate; 
  try 
    LangList.Clear; 
    for i:=0 to ALangList.Count-1 do begin 
      LangItem:=ALangList.Items[i]; 
      LangList.Add(LangItem^.LangName); 
    end; 
    LangIndex:=ALangIndex; 
  finally 
    LangList.EndUpdate; 
  end; 
end; 
 
//record all assigned language object, when change language, pdate them all 
//2003.03.17 
procedure TLangMgr.AddLangObj(LangObj:ILangIntf); 
begin 
  ALangObjList.Add(Pointer(LangObj)); 
end; 
 
//remove an language object from list 
//2003.03.17 
procedure TLangMgr.RemoveLangObj(LangObj:ILangIntf); 
begin 
  ALangObjList.Remove(Pointer(LangObj)); 
end; 
 
//change to another language, update all language object 
//2003.03.17 
procedure TLangMgr.ChangeLanguage(LangIndex:Integer); 
var 
  LangItem:PLangItem; 
  I:Integer; 
  LangObj:ILangIntf; 
begin 
  if (LangIndex>=0) and (LangIndex=0) and (ALangIndex