Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Mehrsprachingkeit (https://www.delphipraxis.net/206148-mehrsprachingkeit.html)

wschrabi 24. Nov 2020 08:40

Mehrsprachingkeit
 
Hallo,
ich habe eine UNIT mit zug. DFM und möchte nun alle CAPTIONs der Objekte mit Objektnamen in eine Liste haben.
so Zb:
Delphi-Quellcode:
Form1.Label1.Caption:='LabelText1_deutsch';
Form1.Button1.Caption := ' ButtoneText1';
Ziel ist eine maschinelle Übersetzung der Strings des Prg zu ermöglichen. Dh. ich mach dann eine Routine wo die Strings durch
Delphi-Quellcode:
capstr[1,Sprache]:='LabelText1_deutsch';
ersetzt werden und dann kann ich je nach Sprache-INdex die Captions multisprachig schalten.

Weiß wer wie man so was macht? Hat jemand das Problem der Mehrsparchigkeit schon mal gehabt?
DANKE
WS

zeras 24. Nov 2020 08:44

AW: Mehrsprachingkeit
 
Der Ansatz ist gut, nur scheitert es dann an den Dialogen, die vom jeweiligen OS in der Sprache des Computers zur Verfügung gestellt werden.
Du darfst dann aber nicht nur Captions, sondern auch Text suchen.
Ich nutze tsilang, wobei dies nicht kostenlos ist.

Sailor 24. Nov 2020 09:29

AW: Mehrsprachingkeit
 
Delphi-Quellcode:
  PROCEDURE GetComponentCaptions(frm:TForm);
   VAR
    texts: TStringList;
     comp: TComponent;
     capt: String;
        i: Integer;

   BEGIN
    texts := TStringList.Create;
    TRY
     WITH texts
      DO BEGIN
          Duplicates := dupIgnore;
          Sorted := True;
          FOR i:=0 TO frm.ComponentCount-1
           DO BEGIN
               comp := frm.Components[i];
               capt := comp.Caption;
               IF (comp.Name <> '')
                 AND
                  (capt <> '')
                THEN Add(comp.Name+'='+capt)
              END;
          SaveToFile(CaptionFileName)
         END;
    FINALLY
     texts.Free
    END
   END;
Du mußt dann nur über alle Forms iterieren, Dialoge müssen geöffnet sein. Die Beschriftungen der Buttons in den Dialogen kann auch geändert werden, bis auf wenige Ausnahmen.

Ach so, beim Setzen der Sprache dann genau umgekehrt verfahren:
Finde comp.Name
Setze die Caption

himitsu 24. Nov 2020 10:10

AW: Mehrsprachingkeit
 
Von GNU-gettext gibt es für Delphi mehrere Implementierungen. (auch in den JEDI ist was drin)

Und dann gibt es auch
http://docwiki.embarcadero.com/RADSt...ger_in_the_IDE
http://docwiki.embarcadero.com/RADSt...s_to_a_Project

wschrabi 24. Nov 2020 10:20

AW: Mehrsprachingkeit
 
Tausend DANK! Sailer super! Genau so wollte ich es. SUPER!:lol:

wschrabi 24. Nov 2020 10:41

AW: Mehrsprachingkeit
 
Zitat:

Zitat von Sailor (Beitrag 1477828)
Delphi-Quellcode:
  PROCEDURE GetComponentCaptions(frm:TForm);
Du mußt dann nur über alle Forms iterieren, Dialoge müssen geöffnet sein. Die Beschriftungen der Buttons in den Dialogen kann auch geändert werden, bis auf wenige Ausnahmen.

Ach so, beim Setzen der Sprache dann genau umgekehrt verfahren:
Finde comp.Name
Setze die Caption

Frage: Ich möchte die Files *.dfm einlesen wie kann ich da die frm:TFORM machen?
wie kann man das abändern, dass er die Files (*.dfm) in einer Listbox interiert. Die Listbox mit den *.dfm hab ich ja.

oder: wie kann ich eine Liste aller TForms erhalten von einem fremden DelphiPRoject?
Edit: hab das hier gefunden: https://stackoverflow.com/questions/...of-my-software

Mein ansatz ist:

Delphi-Quellcode:
unit Unit1MergeMe;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, system.IOUtils, StdCtrls ;

type
  TFormFIND = class(TForm)
    ListBoxtmp: TListBox;
    Edit1: TEdit;
    Label1: TLabel;
    Button1: TButton;
    OpenDialog1: TOpenDialog;
    Button2: TButton;
    OpenDialog2: TOpenDialog;
    Button3: TButton;
   // gtPDFDocument1: TgtPDFDocument;
   // gtPDFDocumentCOVER: TgtPDFDocument;
    ListBoxEnd: TListBox;
    SaveDialog1: TSaveDialog;
    Memo1: TMemo;
    CheckBox1: TCheckBox;
    //gtPDFDocument2: TgtPDFDocument;
    CheckBox2: TCheckBox;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
      procedure MakeFileList(listboxtmp: Tlistbox; teil:array of string; Verzeichnis: string);
      procedure FindAllFiles(const FileList: tstrings;RootFolder: string; Maske: array of string; Recurse: Boolean = False);
      function GetTempDirectory: String;
      PROCEDURE GetComponentCaptions(frm:TForm; FN: string);
     
     
     
   
  public
    { Public-Deklarationen }
  end;

var
  FormFIND: TFormFIND;
  mypath: string;

implementation

{$R *.dfm}


procedure TFormFIND.Button1Click(Sender: TObject);
begin
   if opendialog1.Execute then
      begin
        edit1.Text:= Opendialog1.FileName;
      end;

end;

procedure TFormFIND.Button2Click(Sender: TObject);
begin
   if opendialog2.execute then
      begin
        makefilelist(listboxtmp,['*.dfm'],extractfilepath(opendialog2.filename));

      end;
end;


function filenameconform(fn:string):string;
begin
  fn:=stringreplace(fn,' ','_',[rfReplaceall]);
  fn:=stringreplace(fn,'.','_',[rfReplaceall]);
  fn:=stringreplace(fn,':','_',[rfReplaceall]);
  result:=fn;
end;

procedure TFormFIND.Button3Click(Sender: TObject);
var
  i: Integer;
  mymergedfn: string;
begin
listboxend.Clear;



mymergedfn:=filenameconform(datetimetostr(now));


savedialog1.filename:=format('%sGREPFORM.pas',[mypath]);
if Savedialog1.execute then
   begin
   for i := 0 to listboxtmp.Count-1 do
      begin
      mypath:=extractfilepath(listboxtmp.Items[i]);
      GetComponentCaptions(listboxtmp.Items[i],savedialog1.filename);
     
      end;
   
   
   end;
   


end;

PROCEDURE formfind.GetComponentCaptions(frm:TForm; FN: string);
   VAR
    texts: TStringList;
     comp: TComponent;
     capt: String;
        i: Integer;

   BEGIN
    texts := TStringList.Create;
    TRY
     WITH texts
      DO BEGIN
          Duplicates := dupIgnore;
          Sorted := True;
          FOR i:=0 TO frm.ComponentCount-1
           DO BEGIN
               comp := frm.Components[i];
               capt := comp.Caption;
               IF (comp.Name <> '')
                 AND
                  (capt <> '')
                THEN Add(comp.Name+'='+capt)
              END;
          SaveToFile(FN)
         END;
    FINALLY
     texts.Free
    END
   END;

   
function TFormFIND.GetTempDirectory: String;
var
  tempFolder: array[0..MAX_PATH] of Char;
begin
  //GetTempPath(MAX_PATH, @tempFolder);
  //result := StrPas(tempFolder);
  result:=TPath.GetTempPath;
end;


procedure TFormFIND.FindAllFiles(const FileList: tstrings;RootFolder: string; Maske: array of string; Recurse: Boolean = False);
var
  SR: TSearchRec;
  i : integer;
begin
  //RootFolder := IncludeTrailingPathDelimiter(RootFolder);

  if Recurse then
    if FindFirst(RootFolder + '*.*', faAnyFile, SR) = 0 then
    try
      repeat
        if SR.Attr and faDirectory = faDirectory then
            // --> ein Verzeichnis wurde gefunden
            // der Verzeichnisname steht in SR.Name
            // der vollständige Verzeichnisname (inkl. darüberliegender Pfade) ist
            // RootFolder + SR.Name
          if (SR.Name <> '.') and (SR.Name <> '..') then
            FindAllFiles(FileList, RootFolder + SR.Name, Maske, Recurse);
      until FindNext(SR) <> 0;
    finally
      FindClose(SR);
    end;
  i := 0;
  repeat
    begin
      if FindFirst(RootFolder + Maske[i], faAnyFile, SR) = 0 then
      try
        repeat
          if SR.Attr and faDirectory <> faDirectory then
          begin
            // --> eine Datei wurde gefunden
            // der Dateiname steht in SR.Name
            // der vollständige Dateiname (inkl. Pfadangabe) ist
            // RootFolder + SR.Name
            FileList.Add(RootFolder + SR.Name);
          end;
        until FindNext(SR) <> 0;
      finally
        FindClose(SR);
      end;
      i := i + 1;
    end
  until
    i = high(maske) + 1;
end;


function ReportTime(const Name: string; const FileTime: TFileTime): string;
 var
   SystemTime, LocalTime: TSystemTime;
 begin
   if not FileTimeToSystemTime(FileTime, SystemTime) then
     RaiseLastOSError;
   if not SystemTimeToTzSpecificLocalTime(nil, SystemTime, LocalTime) then
     RaiseLastOSError;
   result:=Name + ': ' + DateTimeToStr(SystemTimeToDateTime(LocalTime));
 end;

procedure GetBuildInfo(var V1, V2, V3, V4: word);
var
  VerInfoSize, VerValueSize, Dummy: DWORD;
  VerInfo: Pointer;
  VerValue: PVSFixedFileInfo;
begin
  VerInfoSize := GetFileVersionInfoSize(PChar(ParamStr(0)), Dummy);
  if VerInfoSize > 0 then
  begin
      GetMem(VerInfo, VerInfoSize);
      try
        if GetFileVersionInfo(PChar(ParamStr(0)), 0, VerInfoSize, VerInfo) then
        begin
          VerQueryValue(VerInfo, '\', Pointer(VerValue), VerValueSize);
          with VerValue^ do
          begin
            V1 := dwFileVersionMS shr 16;
            V2 := dwFileVersionMS and $FFFF;
            V3 := dwFileVersionLS shr 16;
            V4 := dwFileVersionLS and $FFFF;
          end;
        end;
      finally
        FreeMem(VerInfo, VerInfoSize);
      end;
  end;
end;

function GetBuildInfoAsString: string;
var
  V1, V2, V3, V4: word;
begin
  GetBuildInfo(V1, V2, V3, V4);
  Result := IntToStr(V1) + '.' + IntToStr(V2) + '.' +
    IntToStr(V3) + '.' + IntToStr(V4);
end;

procedure TFormFIND.FormCreate(Sender: TObject);

var
   targetinfo: string;
   fad: TWin32FileAttributeData;
   
begin

  if not GetFileAttributesEx(PChar(Application.ExeName), GetFileExInfoStandard, @fad) then
    RaiseLastOSError;
  //ReportTime('Created', fad.ftCreationTime);
  //ReportTime('Modified', fad.ftLastWriteTime);
  //ReportTime('Accessed', fad.ftLastAccessTime);

   {$IFDEF WIN64}
      targetinfo:=' (x64 Architecture)';
     {$ELSE}
      targetinfo:=' Architecture: 32bit';
     {$ENDIF}

   targetinfo := targetinfo + format(' %s : %s',
         [ReportTime('Created', fad.ftCreationTime),
         ReportTime('Modified', fad.ftLastWriteTime)]) ;

  FormFIND.Caption := FormFIND.Caption+' - Build: ' + GetBuildInfoAsString + targetinfo;

end;

procedure TFormFIND.MakeFileList(listboxtmp: tlistbox; teil:array of string; Verzeichnis: string);
var
  Files: TStrings;
  i: integer;
begin
  Files := TStringList.Create;
  try
  //  procedure FindAllFiles(const FileList: tstrings;RootFolder: string; Maske: array of string; Recurse: Boolean = True);

    FindAllFiles(files, Verzeichnis, teil, false);
    for i := Files.Count -1 downto 0 do
    begin
        ListBOxtmp.Items.Add(widestring(Files[i]));
        //DeleteFile(Files[i]);
    end;



  finally

    Files.Free;
  end;
end;

end.

DANKE

wschrabi 24. Nov 2020 11:33

AW: Mehrsprachingkeit
 
Liste der Anhänge anzeigen (Anzahl: 1)
Also ich hab jetzt so den Ansatz:
in MainForm hab ich von DELPHIUEBESTZ-Project alle Forms in CreateForm drin und mach eine Stringlist.
Delphi-Quellcode:
procedure TFormFG.FormCreate(Sender: TObject);
begin
  MyForms := TStringList.Create;
  Application.CreateForm(TForm1, Form1); Myforms.items.add('Form1');
  Application.CreateForm(TForm2, Form2); Myforms.items.add('Form2');
  Application.CreateForm(TFrmBlatt, FrmBlatt); Myforms.items.add('FrmBlatt');
  Application.CreateForm(TForm4, Form4); Myforms.items.add('Form4');
  Application.CreateForm(TForm4TC, Form4TC); Myforms.items.add('Form4TC');
  Application.CreateForm(TForm5TC, Form5TC); Myforms.items.add('Form5TC');
  Application.CreateForm(TForm6, Form6); Myforms.items.add('Form6');
  Application.CreateForm(TFormindi2, Formindi2); Myforms.items.add('Formindi2');
  Application.CreateForm(TFormindi1, Formindi1); Myforms.items.add('Formindi1');
  Application.CreateForm(TForm8, Form8); Myforms.items.add('Form8');
  Application.CreateForm(TForm7, Form7); Myforms.items.add('Form7');
  Application.CreateForm(TUSBErrorForm, USBErrorForm); Myforms.items.add('USBErrorForm');
  Application.CreateForm(TForm9, Form9); Myforms.items.add('Form9');
  Application.CreateForm(TForm10, Form10); Myforms.items.add('Form10');
  Application.CreateForm(TMainForm, MainForm); Myforms.items.add('MainForm');
  Application.CreateForm(TInfoForm, InfoForm); Myforms.items.add('InfoForm');
  Application.CreateForm(TForm11, Form11); Myforms.items.add('Form11');
  Application.CreateForm(TForm4, Form4); Myforms.items.add('Form4');
  Application.CreateForm(TForm5, Form5); Myforms.items.add('Form5');
  Application.CreateForm(TForm12, Form12); Myforms.items.add('Form12');
  Application.CreateForm(TForm13, Form13); Myforms.items.add('Form13');
  Application.CreateForm(TForm111, Form111); Myforms.items.add('Form111');
  Application.CreateForm(TForm14, Form14); Myforms.items.add('Form14');
  Application.CreateForm(TFormMergeMe, FormMergeMe); Myforms.items.add('FormMergeMe');

end;
und dann lass ich die loop durch:

Delphi-Quellcode:
procedure TFormFIND.Button3Click(Sender: TObject);
var
  i: Integer;
  mymergedfn: string;
begin
listboxend.Clear;



mymergedfn:=filenameconform(datetimetostr(now));


savedialog1.filename:=format('%sGREPFORM.pas',[mypath]);
if Savedialog1.execute then
   begin
   for i := 0 to myforms.Count-1 do
      begin
      GetComponentCaptions(TForm(myforms[i]),savedialog1.filename);
     
      end;
   
   
   end;
   


end;
Doch leider ist der Code von oben nicht ok. Siehe Bild anbei.

So wie ich das sehe und in https://www.tek-tips.com/viewthread.cfm?qid=1025706 steht
muss man zuerst fragen ob die TComponent einen Caption hat. und dann zb TLabel(com).Caption machen.

oder? WIe kann man das machen?

Oder hier: man muss mit try machen:
Delphi-Quellcode:
procedure bla(c: TComponent)
   for i := 0 to c.ComponentsCount-1 do begin
      bla(c.Components[i])
      try
         (c.Components[i] as TControl).Caption := str
      except
      end
   end
end
DANKE

Der schöne Günther 24. Nov 2020 11:48

AW: Mehrsprachingkeit
 
Zitat:

Zitat von himitsu (Beitrag 1477834)
Von GNU-gettext gibt es für Delphi mehrere Implementierungen

Nutzen wir auch seit mehreren Jahren in unseren Delphi-Projekten. Kostet nichts, funktioniert super, und nutzt mit .po ein Standardformat. Ein Kunde hatte sich bspw. die komplette Software selbst in seine Sprache übersetzt und kein einziges mal dafür bei uns gefragt was er tun muss 😎

wschrabi 24. Nov 2020 11:56

AW: Mehrsprachingkeit
 
Habe das jetzt so gelöst:

In UnitFGMain:
Delphi-Quellcode:

uses Unit1MergeMe,
  Unit1 in '..\Unit1.dfm' {Form1},
  Unit2 in '..\Unit2.pas' {Form2},
  Unit3 in '..\Unit3.pas' {Form3},
  Unit4TC in '..\Unit4TC.pas' {Form4TC},
  Unit5TC in '..\Unit5TC.pas' {Form5TC},
  Unit6 in '..\Unit6.pas' {Form6},
  Unitindi2 in '..\Unitindi2.pas' {Formindi2},
  Unitindi1 in '..\Unitindi1.pas' {Formindi1},
  Unit8 in '..\Unit8.pas' {Form8},
  Unit7 in '..\Unit7.pas' {Form7},
  RegExpr in '..\RegExpr.pas',
  USBError in '..\USBError.pas' {USBErrorForm},
  md5 in '..\md5.pas',
  PrintFormUnit in '..\PrintFormUnit.pas' {Form9},
  Unit10 in '..\Unit10.pas' {Form10},
  DevReader in '..\HIDKomponente\HIDKomponente\DEMOS\Delphi\ReadWriteDemo\DevReader.pas' {MainForm},
  Info in '..\HIDKomponente\HIDKomponente\DEMOS\Delphi\ReadWriteDemo\Info.pas' {InfoForm},
  Unit11 in '..\Unit11.pas' {Form11},
  Unit4 in '..\Unit4.pas' {Form4},
  Unit5 in '..\Unit5.pas' {Form5},
  Unit12 in '..\Unit12.pas' {Form12},
  Unit13 in '..\Unit13.pas' {Form13},
  SetupApi in '..\HIDKomponente\HIDKomponente\SetupApi.pas',
  ModuleLoader in '..\HIDKomponente\HIDKomponente\ModuleLoader.pas',
  WinConvTypes in '..\HIDKomponente\HIDKomponente\WinConvTypes.pas',
  Unit111 in '..\SQLite\Unit111.pas' {Form111},
  Unit14 in '..\Unit14.pas' {Form14},
  UnitMergeMe in '..\UnitMergeMe.pas' {FormMergeMe},
  UnitTrans in '..\UnitTrans.pas';

{$R *.RES}

;

procedure TFormFG.Button1Click(Sender: TObject);
begin
   formfind.showmodal;
end;

procedure TFormFG.FormCreate(Sender: TObject);
begin
  MyForms := TStringList.Create;
  Application.CreateForm(TForm1, Form1); Myforms.items.add('Form1');
  Application.CreateForm(TForm2, Form2); Myforms.items.add('Form2');
  Application.CreateForm(TFrmBlatt, FrmBlatt); Myforms.items.add('FrmBlatt');
  Application.CreateForm(TForm4, Form4); Myforms.items.add('Form4');
  Application.CreateForm(TForm4TC, Form4TC); Myforms.items.add('Form4TC');
  Application.CreateForm(TForm5TC, Form5TC); Myforms.items.add('Form5TC');
  Application.CreateForm(TForm6, Form6); Myforms.items.add('Form6');
  Application.CreateForm(TFormindi2, Formindi2); Myforms.items.add('Formindi2');
  Application.CreateForm(TFormindi1, Formindi1); Myforms.items.add('Formindi1');
  Application.CreateForm(TForm8, Form8); Myforms.items.add('Form8');
  Application.CreateForm(TForm7, Form7); Myforms.items.add('Form7');
  Application.CreateForm(TUSBErrorForm, USBErrorForm); Myforms.items.add('USBErrorForm');
  Application.CreateForm(TForm9, Form9); Myforms.items.add('Form9');
  Application.CreateForm(TForm10, Form10); Myforms.items.add('Form10');
  Application.CreateForm(TMainForm, MainForm); Myforms.items.add('MainForm');
  Application.CreateForm(TInfoForm, InfoForm); Myforms.items.add('InfoForm');
  Application.CreateForm(TForm11, Form11); Myforms.items.add('Form11');
  Application.CreateForm(TForm4, Form4); Myforms.items.add('Form4');
  Application.CreateForm(TForm5, Form5); Myforms.items.add('Form5');
  Application.CreateForm(TForm12, Form12); Myforms.items.add('Form12');
  Application.CreateForm(TForm13, Form13); Myforms.items.add('Form13');
  Application.CreateForm(TForm111, Form111); Myforms.items.add('Form111');
  Application.CreateForm(TForm14, Form14); Myforms.items.add('Form14');
  Application.CreateForm(TFormMergeMe, FormMergeMe); Myforms.items.add('FormMergeMe');

end;
und im HAuptModul hier:
Delphi-Quellcode:
unit Unit1MergeMe;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, system.IOUtils, StdCtrls ;

type
  TFormFIND = class(TForm)
    ListBoxtmp: TListBox;
    Edit1: TEdit;
    Label1: TLabel;
    Button1: TButton;
    OpenDialog1: TOpenDialog;
    Button2: TButton;
    OpenDialog2: TOpenDialog;
    Button3: TButton;
   // gtPDFDocument1: TgtPDFDocument;
   // gtPDFDocumentCOVER: TgtPDFDocument;
    ListBoxEnd: TListBox;
    SaveDialog1: TSaveDialog;
    Memo1: TMemo;
    CheckBox1: TCheckBox;
    //gtPDFDocument2: TgtPDFDocument;
    CheckBox2: TCheckBox;
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
      function GetTempDirectory: String;
      PROCEDURE GetComponentCaptions(frm:TForm; FN: string);
     
     
     
   
  public
    { Public-Deklarationen }
  end;

var
  FormFIND: TFormFIND;
  mypath: string;

implementation

{$R *.dfm}

uses UnitFGMain, Typinfo;

const
CSCaption = 'Caption';

procedure TFormFIND.Button1Click(Sender: TObject);
begin
   if opendialog1.Execute then
      begin
        edit1.Text:= Opendialog1.FileName;
      end;

end;



function filenameconform(fn:string):string;
begin
  fn:=stringreplace(fn,' ','_',[rfReplaceall]);
  fn:=stringreplace(fn,'.','_',[rfReplaceall]);
  fn:=stringreplace(fn,':','_',[rfReplaceall]);
  result:=fn;
end;

procedure TFormFIND.Button3Click(Sender: TObject);
var
  i: Integer;
  mymergedfn: string;
begin
savedialog1.filename:=format('%sGREPFORM.pas',[mypath]);
if Savedialog1.execute then
   begin
   for i := 0 to myforms.Count-1 do
      begin
      GetComponentCaptions(TForm(myforms[i]),savedialog1.filename);
      end;
   end;
end;

PROCEDURE Tformfind.GetComponentCaptions(frm: TForm ; FN: string);
   VAR
    texts: TStringList;
     comp: TComponent;
     capt: String;
        i: Integer;
       

   BEGIN

    texts := TStringList.Create;
    TRY
     WITH texts
      DO BEGIN
          Duplicates := dupIgnore;
          Sorted := True;
          FOR i:=0 TO frm.ComponentCount-1
           DO
           begin
               comp := frm.Components[i];
               if comp is TControl then
               begin
               if IsPublishedProp(Comp, CSCaption) then
                  begin
                  capt:=GetStrProp(Comp, CSCaption);

                  IF (comp.Name <> '')
                    AND
                     (capt <> '')
                   THEN Add(comp.Name+'='+capt);

                  end;
               end;
             SaveToFile(FN)
           end;
         END;
    FINALLY
     texts.Free
    END
   END;

   
function TFormFIND.GetTempDirectory: String;
var
  tempFolder: array[0..MAX_PATH] of Char;
begin
  //GetTempPath(MAX_PATH, @tempFolder);
  //result := StrPas(tempFolder);
  result:=TPath.GetTempPath;
end;



function ReportTime(const Name: string; const FileTime: TFileTime): string;
 var
   SystemTime, LocalTime: TSystemTime;
 begin
   if not FileTimeToSystemTime(FileTime, SystemTime) then
     RaiseLastOSError;
   if not SystemTimeToTzSpecificLocalTime(nil, SystemTime, LocalTime) then
     RaiseLastOSError;
   result:=Name + ': ' + DateTimeToStr(SystemTimeToDateTime(LocalTime));
 end;

procedure GetBuildInfo(var V1, V2, V3, V4: word);
var
  VerInfoSize, VerValueSize, Dummy: DWORD;
  VerInfo: Pointer;
  VerValue: PVSFixedFileInfo;
begin
  VerInfoSize := GetFileVersionInfoSize(PChar(ParamStr(0)), Dummy);
  if VerInfoSize > 0 then
  begin
      GetMem(VerInfo, VerInfoSize);
      try
        if GetFileVersionInfo(PChar(ParamStr(0)), 0, VerInfoSize, VerInfo) then
        begin
          VerQueryValue(VerInfo, '\', Pointer(VerValue), VerValueSize);
          with VerValue^ do
          begin
            V1 := dwFileVersionMS shr 16;
            V2 := dwFileVersionMS and $FFFF;
            V3 := dwFileVersionLS shr 16;
            V4 := dwFileVersionLS and $FFFF;
          end;
        end;
      finally
        FreeMem(VerInfo, VerInfoSize);
      end;
  end;
end;

function GetBuildInfoAsString: string;
var
  V1, V2, V3, V4: word;
begin
  GetBuildInfo(V1, V2, V3, V4);
  Result := IntToStr(V1) + '.' + IntToStr(V2) + '.' +
    IntToStr(V3) + '.' + IntToStr(V4);
end;

procedure TFormFIND.FormCreate(Sender: TObject);

var
   targetinfo: string;
   fad: TWin32FileAttributeData;
   
begin

  if not GetFileAttributesEx(PChar(Application.ExeName), GetFileExInfoStandard, @fad) then
    RaiseLastOSError;
  //ReportTime('Created', fad.ftCreationTime);
  //ReportTime('Modified', fad.ftLastWriteTime);
  //ReportTime('Accessed', fad.ftLastAccessTime);

   {$IFDEF WIN64}
      targetinfo:=' (x64 Architecture)';
     {$ELSE}
      targetinfo:=' Architecture: 32bit';
     {$ENDIF}

   targetinfo := targetinfo + format(' %s : %s',
         [ReportTime('Created', fad.ftCreationTime),
         ReportTime('Modified', fad.ftLastWriteTime)]) ;

  FormFIND.Caption := FormFIND.Caption+' - Build: ' + GetBuildInfoAsString + targetinfo;

end;


end.

himitsu 24. Nov 2020 12:40

AW: Mehrsprachingkeit
 
Zitat:

Delphi-Quellcode:
Application.CreateForm(TForm1, Form1); Myforms.items.add('Form1');
Application.CreateForm(TForm2, Form2); Myforms.items.add('Form2');
...

Wem fällt da was auf?
Ganz viel doppelter Code.
* Man kann CreateForm und Items.Add in eine Funktion auslagern und den Namen aus Form.Name verwenden. (kein eventueller Copy&Paste-Fehler beim Namen)
* man kann die "Registrierung" auch im Constructor/OnCreate der Forms erledigen, bzw. in einem gemeinsamen Vorfahren seiner Forms.

Da in myforms nicht der Name, sondern die Instanz beötigt wird, warum ist das keine TObjectList oder bei einer StringList kann man auch zusätzlich das Objekt speichern.
Wobei ich bei StringList.AddObject auch direkt an ein TDictionary<string,TForm> denken würde.

Und da es in Screen.Forms bereits eine Liste "aller" VCL-Forms gibt, warum nicht diese Liste benutzen?

Das GetComponentCaptions nutzt nichts von der Form, also warum ist das dann keine
Delphi-Quellcode:
Class Procedure
?



TComponent.Name oder TForm(string) .... ja, die richtigen Typen sollte man immer verwenden.
Casten wen nötig, aber wenn man castet, dann auch nur zwischen kompatiblen Typen.

Redeemer 24. Nov 2020 13:19

AW: Mehrsprachingkeit
 
Warum verteufeln alle Delphis eigenes XLIFF?

freimatz 24. Nov 2020 13:28

AW: Mehrsprachingkeit
 
Sicher, dass das Delphi eigen ist? (https://en.wikipedia.org/wiki/XLIFF)

wschrabi 24. Nov 2020 15:12

AW: Mehrsprachingkeit
 
Danke herzlichst, für Deine guten Tips, die ich mir zu Herzen nehmen werde.
walter:thumb:

kompi 24. Nov 2020 15:25

AW: Mehrsprachingkeit
 
Aus den Beispielen entnehme ich, dass das Projekt ein VCL Projekt ist.

Hierfür hat Anders Melander mal den "Better Translation Manager" programmiert, den man von seiner Webseite http://melander.dk/ herunterladen kann. Ich benutze diesen Manager in einem Projekt und bin begeistert.

Man muss nur in Delphi vorwählen, dass mit drc Dateien kompiliert werden soll. Dann lädt man die Exe Datei und schon kann man übersetzen. Dies kann man sogar über z.B. Microsoft Translation automatisch übersetzen lassen. Dann noch die Sprachdatei im Manager erstellen und in das Programmverzeichnis kopieren. Das wars.
Alles andere wird durch das Delphi eigene Localization System erledigt.

Es ist keine Änderung im Code notwendig.

Viele Grüße
Kompi

wschrabi 24. Nov 2020 16:18

AW: Mehrsprachingkeit
 
Hallo Hr Detlef Schmitz,
supperrr genau so was brauch eich. Ich habs mit dem Delphi Translation Manager probiert, doch ich hab zwar jetzt in ENU die *.dfm aber er hat nix überstzt.
Denke Dein TIPist viel besser.

SUPER DNAKE

wschrabi 24. Nov 2020 17:14

AW: Mehrsprachingkeit
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Detlef,
ich habe mir den BTM angeguckt und ich kann aber noch nichts automatisch übersetzten lassen.
Einzeln kann ich die CAPTIONS in der ZIELSPRACHENSPalte manuell eingeben und dann Accept Translation klicken. (Bild)
Kannst du es mir zeigen wie man das macht
doch möchte ich es automatisch machen, denn es sind 12000 Terminis.
ich hab auch schon von https://www.freeoffice.com/en/download/dictionaries die en-us und de-at aus den SOX Files ungezipped und in %APPDATA$\LOCAL\Translationmanager\Dictionaries reinkopiert.
Doch es will nicht.
Was mache ich falsch?
DANKE

Redeemer 24. Nov 2020 20:08

AW: Mehrsprachingkeit
 
Zitat:

Zitat von freimatz (Beitrag 1477854)
Sicher, dass das Delphi eigen ist? (https://en.wikipedia.org/wiki/XLIFF)

Das ist in der Delphi-IDE enthalten. Erfunden hat Emba das nicht.

kompi 25. Nov 2020 06:51

AW: Mehrsprachingkeit
 
Man muss sich zum Microsoft Translation Service anmelden, also ein kostenloses Konto bei Microsoft Azure anlegen. In Azure meldet man sich dann zu diesem Dienst an und gibt die entsprechenden Daten in den Settings von BTM an.

Dann kann man diese Funktion in BTM nutzen, in dem man die Funktion Translation -> Auto Translate -> Microsoft Translation Service auswählt. Hat man mehrere Zeilen selektiert, werden diese alle in die jeweilige Sprache übersetzt.

Das schwierigste ist dabei, sich beim Microsoft Translation Service anzumelden. Es finden sich jedoch im Netz diverse Anleitungen.
Alternativ kann man übersetzte Teile zum Translation Memory hinzufügen und an anderer Stelle wieder einfügen.

Gruß Kompi

kompi 25. Nov 2020 06:55

AW: Mehrsprachingkeit
 
Noch ein Zusatz:

Die Dateien, die Du in das Dictionary geladen hast, dienen nicht der Übersetzung, sondern nur zur richtigen Buchstabierung (Spell Check).

Gruß Kompi

TigerLilly 25. Nov 2020 07:03

AW: Mehrsprachingkeit
 
Ergänzung:
Mehrsprachigkeit geht Hand in Hand mit Lokalisierung. Also Formate für Währungen, Zeit, Datum etc. Captions übersetzen ist eines, aber da gibt es auch Menüs, Hints, Ausgabetexte, Reports.
Manche Texte kommen gar nicht aus der App selbst, sondern aus den Tiefen des Compilers bzw des Betriebssystems.

Sinspin 25. Nov 2020 09:10

AW: Mehrsprachingkeit
 
Zitat:

Zitat von TigerLilly (Beitrag 1477909)
Manche Texte kommen gar nicht aus der App selbst, sondern aus den Tiefen des Compilers bzw des Betriebssystems.

Ja, das war mal sehr nervig.
Nun sind alle Delphi-Dialoge von uns, wir verwenden SiComponents fürs übersetzen. Und DevExpress hat für seine eigenen Forms mittlerweile auch gute Übersetzungen die man umschalten kann.
System-Dialoge sind ja schon in der passenden Sprache (solange beim Setup keiner Murks gemacht hat).

TigerLilly 25. Nov 2020 10:24

AW: Mehrsprachingkeit
 
Zitat:

Zitat von Sinspin (Beitrag 1477919)
System-Dialoge sind ja schon in der passenden Sprache (solange beim Setup keiner Murks gemacht hat).

Naja - Computer ist in Englisch und der User schaltet die Oberfläche des Programms auf Französisch. Da erwartet er uU dann alle Dialoge in Französisch.

wschrabi 25. Nov 2020 20:48

AW: Mehrsprachingkeit
 
@kompi DANKE, ich werde es probieren.
@TigerLilly: Ja klar das hatte ich alles berücksichtig, doch in der Änderung der APP hatte ich dann bei den Captions und Titles imme rnur dt Texte. Ursprünglich hatte ich 2 versc App in eng und dt. doch die TBM ist eine Super Hilfe. :thumb:

wschrabi 25. Nov 2020 21:08

AW: Mehrsprachingkeit
 
Zitat:

Zitat von Sinspin (Beitrag 1477919)
Zitat:

Zitat von TigerLilly (Beitrag 1477909)
Manche Texte kommen gar nicht aus der App selbst, sondern aus den Tiefen des Compilers bzw des Betriebssystems.

... wir verwenden SiComponents fürs übersetzen..

Super Tip, koste nicht mal soviel $259,-https://www.tsilang.com/ werde ich mir ansehen. So wie ich es sehe muss man nur ein ICON auf das Form, das anlicken und die ÜBersetzung eingeben (kann das autom. erfolgen?) .
Auch kann man zur RUNTIME auf die eingetragenen Sprachen umschalten. DAS IST SUPER.
DANKE herzlichst
WS:thumb:

zeras 25. Nov 2020 21:24

AW: Mehrsprachingkeit
 
[QUOTE=Sinspin;1477919]
Zitat:

Zitat von TigerLilly (Beitrag 1477909)
Nun sind alle Delphi-Dialoge von uns, wir verwenden SiComponents fürs übersetzen. Und DevExpress hat für seine eigenen Forms mittlerweile auch gute Übersetzungen die man umschalten kann.

Dies hatte ich im Beitrag hier schon gepostet.
Ich bin auch zufrieden mit den Komponenten.

wschrabi 25. Nov 2020 23:12

AW: Mehrsprachingkeit
 
Danke Zeras, ich hab das dort noch nicht verstanden. Jetzt ists klar. DANKE

haentschman 26. Nov 2020 06:16

AW: Mehrsprachingkeit
 
Moin...:P

Wenn du einfache und schnelle Ergebnisse willst...:wink:

https://www.delphipraxis.net/146618-...swerkzeug.html

Auch Übersetzungen zur Laufzeit!!! Auch mußt du keine Language Dateien mitliefern...alles einkompiliert. Editor für die Sprachen.

Klein aber gut...:thumb:

Nachtrag:
"Better Translation Manager" ... kannte ich noch nicht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:01 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz