Report Display Error (FastReport) in Multi-Language Software

4

I have the following error in displaying a report made in FastReport.

ThiserrorstartedtooccurafterinternalizingmysoftwareusingnativeDelphiXE7(Project->Languages->Add)features,whenthesoftwarerunsinnativelanguagethereportisdisplayednormally,butwhenitisIfyouchoseanyadditionallanguage,thesoftwarewilldisplaytheerrormessageastheimage.

Reportdisplaycode:

frRelatorio.Clear;frRelatorio.LoadFromFile(IncludeTrailingPathDelimiter(GetCurrentDir)+'frRelatorio.fr3');frRelatorio.PrepareReport;frRelatorio.ShowReport();

Codethatchangesthelanguage:(Requiredtheunitreinitoftheshipper).

casecbIdioma.ItemIndexof0:lang:=LANG_PORTUGUESE;1:lang:=LANG_SPANISH;end;ifLoadNewResourceModule(lang)<>0thenReinitializeForms;

Ihopethisinformationissufficient,ifnecessaryIcanputanexamplewiththeerror,ifanyonecanhelpme,Ialreadythank.

ADDSampleDownloadLinkGeneratingError: link

    
asked by anonymous 05.01.2015 / 12:27

1 answer

2

Apparently there seems to be no workaround for this error that is generated by class EResNotFound , this exception is thrown when a specific refuse, such as a form that can not be found, a form file ( .dfm ), resource file, etc.

One of the alternatives you can use to circumvent the use of Translation Manager a> from Delphi, is to use Resource Strings . Resource Strings are stored as resources and connected to the executable / library so that those resources can be modified without recompiling the program.

To make this work in your multi-language program, you can create a new Unit (go to FileNewUnit ) in this Unit the translated messages will be placed for each language that will be used in the program . Here's an example:

unit untTraducoes;

interface

resourcestring

// Mensagens em Inglês
EN_FORM_CAPTION          = 'My Program Example';
EN_BTN_INFO_CAPTION      = 'Information';
EN_BTN_CLOSE_CAPTION     = 'Close';
EN_MEMO_TEXT             = 'Some text here';

// Mensagens em Português
PT_FORM_CAPTION          = 'Meu Programa Exemplo';
PT_BTN_INFO_CAPTION      = 'Informação';
PT_BTN_CLOSE_CAPTION     = 'Fechar';
PT_MEMO_TEXT             = 'Algum texto aqui';

implementation

end.

First set the constants below as global.

Const
LANG_PT = 'PT'; // Português
LANG_EN = 'EN'; // Inglês
LANGUAGE_CONFIG_NAME = 'appconfig.ini'; // Arquivo onde vai ser guardado o idioma escolhido
LANGUAGE_DEFAULT     = 'PT'; // Idioma padrão do programa

Now you can create a method that will check the language chosen by the user and apply the translated messages to the desired components.

procedure ApplyLanguage(Lang: string);
begin
If Length(Lang) = 0 then Exit; // Verifica o comprimento da string

If Lang = LANG_PT then begin   // Se for o idioma escolhido, então faça
  self.Caption := PT_FORM_CAPTION;
  self.BtnInfo.Caption := PT_BTN_INFO_CAPTION;
  self.BtnClose.Caption := PT_BTN_CLOSE_CAPTION;
  Self.Memo1.Text := PT_MEMO_TEXT;

end else if Lang = LANG_EN then begin
  self.Caption := EN_FORM_CAPTION;
  self.BtnInfo.Caption := EN_BTN_INFO_CAPTION;
  self.BtnClose.Caption := EN_BTN_CLOSE_CAPTION;
  Self.Memo1.Lines.Text := EN_MEMO_TEXT;    
end;

Application.ProcessMessages;
end;

If you need to save the language chosen by the user, you can save it to a file that stores settings (extension .ini ), and manipulate that file using Unit functions #

// Lembre-se de colocar a unit IniFiles em Uses
procedure ChangeLanguage(Lang: string);
Var
 Ini: TIniFile;
begin
if Length(Lang) = 0 then exit;
Try
  Ini := TIniFile.Create(ExtractFilePath(ParamStr(0)) + LANGUAGE_CONFIG_NAME);
  Ini.WriteString('Opcoes', 'Lang', Lang);
  ApplyLanguage(Lang);
Finally
  Ini.Free;
End;
end;

Now to give the user a choice of language, put the code below in the event IniFiles of OnSelect() :

Var
 Lang: string;
begin
Case cbIdioma.ItemIndex Of
    0: Lang := LANG_PT; // Português 
    1: Lang := LANG_EN; // Inglês
else Lang := LANG_PT;
End;

ChangeLanguage(Lang);

Finally we will create the method responsible for verifying which language will be used when initializing the program.

// Lembre-se de colocar a unit IniFiles em Uses
procedure CheckDefaultLanguage;
Var
 Ini: TIniFile;
 LangOption: string;
begin
Try
  // Cria o .ini no Diretório do executável
  Ini := TIniFile.Create(ExtractFilePath(ParamStr(0)) + LANGUAGE_CONFIG_NAME); 
  if Ini.SectionExists('Opcoes') = False then 
  // Se o arquivo ou seção não existir executa a linha abaixo e define o idioma padrão no arquivo
       Ini.WriteString('Opcoes', 'Lang', LANGUAGE_DEFAULT);

  // Lê o idioma definido no arquivo se não conseguir, devolve o idioma padrão
  LangOption := Ini.ReadString('Opcoes', 'Lang', LANGUAGE_DEFAULT);
  ApplyLanguage(LangOption); // Aplica o idioma escolhido
Finally
  Ini.Free; // Liberamos a instância
End;
end;

In the ComboBox event of the form call the OnCreate() method.

You can make some improvements according to your need, for example, check if a language is available before calling the CheckDefaultLanguage method.

Some images:

The example ( based on your example ) can be downloaded here (TinyUpload) - made in Delphi XE3.

    
16.01.2015 / 03:51