1 Востаннє редагувалося Romanvolja (26.03.2017 09:56:59)

Тема: Іні вайл (мовний файл) у Delphi

Доброго всім дня.
В мене виникла проблема з мовними вайлами.
Щоби змінювати мовний інтерфайс додатку я написав наступний код:

unit Main;
...

    { Public declarations }
  end;
    TLangList = record
      LangName: string;
      LangFileName: string;
    end;

var
  Main_Fr: TMain_Fr;
  SettIniFile, LangIniFile: TIniFile;
  IniDefLang:integer;
  LangSrcRec: TSearchRec;
  LangList: array of TLangList;
  TimerFunction, TimerExitFunc:byte;

implementation
...

procedure CreateLangMenu;
var
  i: integer;
  NewLangMenu: TMenuItem;
begin
  try
    try
      i:=1;
      if FindFirst(ExtractFilePath(Application.ExeName)+'Lang\*.ini', faAnyFile, LangSrcRec) = 0 then
        begin
          repeat
            LangIniFile:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'Lang\'+LangSrcRec.Name);
            SetLength(LangList,i+1);
            LangList[i].LangFileName:=LangSrcRec.Name;
            LangList[i].LangName:=LangIniFile.ReadString('Language Info','LangName','? Language');
            NewLangMenu:=TMenuItem.Create(Main_Fr.English_MIt);
            NewLangMenu.Caption:=LangList[i].LangName;
            NewLangMenu.GroupIndex:=1;
            NewLangMenu.RadioItem:=True;
            NewLangMenu.OnClick:=Main_Fr.LanguagesClick;
            Main_Fr.Languages_MIt.Add(NewLangMenu);
            Inc(i);
          until FindNext(LangSrcRec) <> 0;
        end;
        finally
          FindClose(LangSrcRec);
          LangIniFile.Free;
        end;
  except
    MessageDlg('ERROR! Language *.ini file corrupt',mtError,[mbYes],0);
  end;
end;
...

procedure TMain_Fr.FormCreate(Sender: TObject);
begin
  SettIniFile:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'Sett\Sett.cfg');
  IniDefLang:=SettIniFile.ReadInteger('options','Language',0);
  try
    CreateLangMenu;
    except
    MessageDlg('ERROR! Main config file corrupt!',mtError,[mbYes],0);
  end;
  Main_Fr.LanguagesClick(Main_Fr.Languages_MIt.Items[IniDefLang]);
end;           
...

procedure TMain_Fr.FormDestroy(Sender: TObject);
begin
  try
    SettIniFile.Free;
  except
  end;
end;
...

procedure TMain_Fr.LanguagesClick(Sender: TObject);
begin
  if (Sender is TMenuItem) then
    begin
      (Sender as TMenuItem).Checked:=True;
        try
          try
            LangIniFile:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'Lang\'+LangList[Languages_MIt.IndexOf(Sender as TMenuItem)].LangFileName);
            File_MIt.Caption:=LangIniFile.ReadString('Main Menu','File','File');
            NewDatabase_MIt.Caption:=LangIniFile.ReadString('Main Menu','New Database','New Database');
            OpenDatabase_MIt.Caption:=LangIniFile.ReadString('Main Menu','Open Database','Open Database');
            SaveAsDatabase_MIt.Caption:=LangIniFile.ReadString('Main Menu','Save As Database','Save As Database');
            Exit_MIt.Caption:=LangIniFile.ReadString('Main Menu','Exit','Exit');
...
            RiderBase_Fr.Is_ChBx.Caption:=LangIniFile.ReadString('Rider Form','Is','Is');
            RiderBase_Fr.Fruiting_ChBx.Caption:=LangIniFile.ReadString('Rider Form','Fruiting','Fruiting');
            RiderBase_Fr.Desirable_ChBx.Caption:=LangIniFile.ReadString('Rider Form PanelForm','Desirable','Desirable');
            RiderBase_Fr.Cancel_Bt.Caption:=LangIniFile.ReadString('Rider Form','Cancel','Cancel');
            RiderBase_Fr.Apply_Bt.Caption:=LangIniFile.ReadString('Rider Form','Apply','Apply');
...
            SettIniFile.WriteInteger('options','Language',(Sender as TMenuItem).MenuIndex);
          finally
            LangIniFile.Free;
          end;
        except
          MessageDlg('ERROR! Lang *.ini file corrupt',mtError,[mbYes],0);
        end;
    end;
end;

Проблема в тому що основну форму перекладає, а інші не хоче.
При запуску додатку випливає наступне вікно з повідомленням:
http://img.hurtom.com/i/2017/03/12cbf89.jpg
Після закриття даного діалогу додаток відкривається де основна фома(Main_Fr) перекладена а інші неперекладені.

Та коли я видаляю з проекту частину коду, що відповідає за переклад інших форм (У даному коді 92-96 рядки) і компілюю проект то після цього при запуску додатку діалогове вікно не зявляєтья.

Чесно сказати, що я зайшов в глухий кут і не можу вирішити цієї помилки тому звертаюся до усіх за допомогою.

2

Re: Іні вайл (мовний файл) у Delphi

Рядки 102-104 змініть на щось таке:

except
on E : Exception do
// ставите breakpoint і дивитесь у чому саме річ
      ShowMessage(E.ClassName+' помилка з повідомленням : '+E.Message);
          MessageDlg('ERROR! Lang *.ini file corrupt',mtError,[mbYes],0);
        end;

Так ви відловите точне повідомлення помилки. Також не забувайте про таку річ як Debug та breakpoints.
Продебажте код, можливо у вас там форма непроініціалізована.

Подякували: Torbins1

3

Re: Іні вайл (мовний файл) у Delphi

DOP написав:

Продебажте код, можливо у вас там форма непроініціалізована.

Напевно взагалі не створена.

Подякували: kisilam1

4

Re: Іні вайл (мовний файл) у Delphi

Romanvolja написав:
  try
    SettIniFile.Free;
  except
  end;

Ай-яй-яй! Порожній except - це як би біатлоніст на змаганні випадково прострелив собі ногу, і замість того, щоб звернутися до лікарів, вколов знеболювального і побіг далі. Скоріше за все, це змагання буде для нього останнім.

Подякували: kisilam, ostap34PHP2

5

Re: Іні вайл (мовний файл) у Delphi

Проблему вирішив за рахунок змінних

unit Main;
...
 
    { Public declarations }
  end;
    TLangList = record
      LangName: string;
      LangFileName: string;
    end;
 
var
  Main_Fr: TMain_Fr;
  SettIniFile, LangIniFile: TIniFile;
  IniDefLang:integer;
  LangSrcRec: TSearchRec;
  LangList: array of TLangList;
  TimerFunction, TimerExitFunc:byte;
//Тут створив змінні
  RiderBase_FrIs_ChBxCaption, RiderBase_FrFruiting_ChBxCaption,
  RiderBase_FrDesirable_ChBxCaption, RiderBase_FrCancel_BtCaption,
  RiderBase_FrApply_BtCaption : String;
 
implementation
...

Дальше їм присвоїв значення з Ini файлу

procedure TMain_Fr.LanguagesClick(Sender: TObject);
begin
  if (Sender is TMenuItem) then
    begin
      (Sender as TMenuItem).Checked:=True;
        try
          try
            LangIniFile:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'Lang\'+LangList[Languages_MIt.IndexOf(Sender as TMenuItem)].LangFileName);
            File_MIt.Caption:=LangIniFile.ReadString('Main Menu','File','File');
...
// тут присвоїв ім значення з Ini файлу
            RiderBase_FrIs_ChBxCaption:=LangIniFile.ReadString('Rider Form','Is','Is');
            RiderBase_FrFruiting_ChBxCaption:=LangIniFile.ReadString('Rider Form','Fruiting','Fruiting');
            RiderBase_Fr.Desirable_ChBx.Caption:=LangIniFile.ReadString('Rider Form PanelForm','Desirable','Desirable');
            RiderBase_FrCancel_BtCaption:=LangIniFile.ReadString('Rider Form','Cancel','Cancel');
            RiderBase_FrApply_BtCaption:=LangIniFile.ReadString('Rider Form','Apply','Apply');
...

Після цього в unit Riderbase Компонентам надав значення змінних

unit Riderbase;

interface

uses
  Windows,
...
procedure TRiderBase_Fr.FormActivate(Sender: TObject);
begin
  RiderBase_Fr.Is_ChBx.Caption:=RiderBase_FrIs_ChBxCaption;
  RiderBase_Fr.Fruiting_ChBx.Caption:=RiderBase_FrFruiting_ChBxCaption;
  RiderBase_Fr.Desirable_ChBx.Caption:=RiderBase_FrDesirable_ChBxCaption;
  RiderBase_Fr.Cancel_Bt.Caption:=RiderBase_FrCancel_BtCaption;
  RiderBase_Fr.Apply_Bt.Caption:=RiderBase_FrApply_BtCaption;
 end;

Правда тут багато писанини, але іншого рішення я не знайшов.
Дякую що відгукнулися

6 Востаннє редагувалося Vi (27.03.2017 20:32:04)

Re: Іні вайл (мовний файл) у Delphi

Я б зробив так:

procedure TMain_Fr.LanguagesClick(Sender: TObject);
var appath,filelang:string;
begin
  appath:=ExtractFilePath(ParamStr(0));
  if (Sender is TMenuItem) then
    begin
     (Sender as TMenuItem).Checked:=True;
     filelang:=appath+'Lang\'+LangList[Languages_MIt.IndexOf(Sender as TMenuItem)].LangFileName;
      if not FileExists(filelang) then begin
       ShowMessage(filelang+' нема.'); exit;
      end;
            LangIniFile:=TIniFile.Create(filelang);
        
            File_MIt.Caption:=LangIniFile.ReadString('Main Menu','File','File');
            NewDatabase_MIt.Caption:=LangIniFile.ReadString('Main Menu','New Database','New Database');
            OpenDatabase_MIt.Caption:=LangIniFile.ReadString('Main Menu','Open Database','Open Database');
            SaveAsDatabase_MIt.Caption:=LangIniFile.ReadString('Main Menu','Save As Database','Save As Database');
            Exit_MIt.Caption:=LangIniFile.ReadString('Main Menu','Exit','Exit');
...
            RiderBase_Fr.Is_ChBx.Caption:=LangIniFile.ReadString('Rider Form','Is','Is');
            RiderBase_Fr.Fruiting_ChBx.Caption:=LangIniFile.ReadString('Rider Form','Fruiting','Fruiting');
            RiderBase_Fr.Desirable_ChBx.Caption:=LangIniFile.ReadString('Rider Form PanelForm','Desirable','Desirable');
            RiderBase_Fr.Cancel_Bt.Caption:=LangIniFile.ReadString('Rider Form','Cancel','Cancel');
            RiderBase_Fr.Apply_Bt.Caption:=LangIniFile.ReadString('Rider Form','Apply','Apply');
...
            SettIniFile.WriteInteger('options','Language',(Sender as TMenuItem).MenuIndex);

            LangIniFile.Free;


    end;
end;
Подякували: Romanvolja1

7

Re: Іні вайл (мовний файл) у Delphi

Vi написав:

Я б зробив так:

Щиро вам дякую Ваше рішення набагато краще за моє  *YAHOO*

8

Re: Іні вайл (мовний файл) у Delphi

Якщо в списку Auto Create Forms порожньо, то рядки у будь якому випадку доведеться десь зберігати. Змінні - це нормальне рішення, але красивіше оформити це у рекорди: https://sourceforge.net/p/freelaunch/co … nguage.pas Якщо хочеться зменшити кількість писанини, то є усілякі бібліотеки, які дозволяють обійтися взагалі кількома рядками коду.