乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Delphi實現(xiàn)多語言界面

       刀下巴 2015-11-13

      Delphi實現(xiàn)多語言界面

      用Delphi實現(xiàn)多語言界面

        關鍵字:多語言界面,Delphi,國際化,本地化。

        隨著Internet在全球的普及,一個軟件開發(fā)者,開發(fā)出來的產(chǎn)品可以隨意發(fā)布到全球各個角落,然而與此同時,開發(fā)出來的產(chǎn)品也面臨著一個新的問題:如何實現(xiàn)各種不同的語言界面,甚至根據(jù)最終用戶的操作系統(tǒng)的語言版本,自動更改語言界面?難道為每一個不同的語言編寫一個不同的版本?不,完全沒有必要。Delphi 5.0作為一個優(yōu)秀的快速RAD開發(fā)工具,可以很容易地實現(xiàn)國際化支持,因為Delphi 5.0內(nèi)置了對多語言界面的支持。

        一個程序,如果需要不同的語言版本,那么應該有一下幾點需要注意的地方[]:

      1. 必須允許你的程序代碼能夠處理好各種語言字符串,例如如果要中文化,必須能夠處理雙字節(jié)。

      2. 你必須設計好你的程序界面,以便能夠使你的程序界面元素有足夠的空間顯示語言文字信息。一般說來,在50個字節(jié)以內(nèi)的英文單詞所表達的意思,用其他的語言來描述的話,長度要超過50字節(jié),但中文是一個例外。特別對于幾個字節(jié)的英文單詞,其他的語言的長度幾乎百分之百要超過英文的長度!因此,必須在控件中留出足夠的長度以便在更改語言之后,還能顯示全部的語言文字信息。

      3. 你必須翻譯所有的資源。

      本文將著重討論如何用Delphi 5.0實現(xiàn)多語言的支持和切換,界面設計和上述要求不在本文討論范圍之內(nèi)。

      要為程序添加語言支持,只要在Delphi主菜單項Project下面選擇LanguagesàAdd…即可。點擊之后出現(xiàn)語言向?qū)?,讀者按照向?qū)нM行操作即可。向?qū)ЫY束之后,會生成一個工程組文件(BPG),最后出現(xiàn)Translation Manager,軟件開發(fā)者可以在這里翻譯所有語言的所有資源,包括字體、位置、文字等等。說明一下:你可以隨時隨地用Project下面的Languages子菜單的功能來添加、刪除、修改各種界面元素。

      做完上述工作之后,我們現(xiàn)在就差切換語言的代碼了。為了切換語言,大家可以使用下面的一個單元[],單元中提供了兩個函數(shù),用來更換語言界面元素,其中LoadNewResourceModule是用來修改文字信息等等,ReinitializeForms用來重新刷新窗體和控件以保證同步。

      ///文件名:MaltiLan.pas
      unit MaltiLan;
      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[I];
          ReloadInheritedComponent(Form, TForm);
        end;
      end;
      end.
      測試程序窗體單元文件如下:

      ///單元文件名:unit1.pas
      unit Unit1;
      interface

      uses
        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./soft/MultiLan.rar>下載。

      后記:其實用INI文件也可以實現(xiàn)多語言界面的切換,好處是可以方便大家隨時添加不同的語言文件,但是,對于一個大型的程序來說,用INI是不現(xiàn)實的。用INI實現(xiàn)語言界面的程序,大家可以到<http://kingron./soft/winupx.rar>下載源代碼和測試程序。


        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多