AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Multilingual mit DLLs u. Unicode - so richtig?
Thema durchsuchen
Ansicht
Themen-Optionen

Multilingual mit DLLs u. Unicode - so richtig?

Ein Thema von TheMiller · begonnen am 31. Aug 2011 · letzter Beitrag vom 3. Sep 2011
 
Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#1

Multilingual mit DLLs u. Unicode - so richtig?

  Alt 31. Aug 2011, 19:35
Hallo,

ich habe jetzt ein System für Mehrsprachenunterstützung fertig, welches auch für Unicode geeignet sein sollte. Ich würde gerne wissen, ob das alles so richtig/in Ordnung ist. Ich weiß, dass es gnugetext etc gibt, ich mag aber nicht noch mehr Abhängigkeiten im Programm haben.

Anmerkungen: Ist angelehnt an Luckies Artikel StringDLLs und an Unicode angepasst (bzw. sollte so sein). Auch habe ich beide Projekte mit FastMM auf Leaks getestet.

Hinweis:
- Beide Projekte haben eine LanguageID-Unit eingebunden, die die Konstanten entählt.

Hier mal der komplette Quelltext:

Von der DLL
Delphi-Quellcode:
library de;

uses
  SysUtils,
  LanguageIDs;

{$R *.res}

function getText(str: Integer): PWideChar;
begin
  case str of
    BUTTON1_C:
      result:='Einloggen';
    BUTTON1_H:
      result:='Hier klicken, um einzuloggen';
  end;
end;

function getCompName(str: PWideChar): PWideChar;
begin
  if (str = 'Button1') then
    result:='Bitte hier nicht drücken';
end;

//Ersetzt später Captions und Hints nach Komponentenname
function _compName(comp: PWideChar; Buffer: PChar; lenBuffer: Integer): Integer; stdcall;
begin
  if Assigned(Buffer) then
    StrLCopy(Buffer, PWideChar(getCompName(comp)), lenBuffer);
  result := length(getCompName(comp));
end;

//Ruft einfach nur Text ab.
function _lang(str: Integer; Buffer: PWideChar; lenBuffer: Integer): Integer; stdcall;
begin
  if Assigned(Buffer) then
    StrLCopy(Buffer, PWideChar(getText(str)), lenBuffer);
  result := length(getText(str));
end;

exports
  _lang,
  _compName;

begin
end.
Haupt-Programm
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Edit1: TEdit;
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    function _l(strName: Integer): String;
    function _cl(compName: String): String;
  end;

  TLang = function (str: Integer; Buffer: PChar; lenBuffer: Integer): Integer; stdcall;
  TComp = function (comp: PChar; Buffer: PChar; lenBuffer: Integer): Integer; stdcall;

var
  Form1: TForm1;
  hLib: THandle;
  s: String;
  Lang: TLang;
  Comp: TComp;
  len: Integer;
  Buffer: PChar;

implementation

{$R *.dfm}

{****** Holt den Text aus der DLL **********}
function TForm1._l(strName: Integer): String;
begin
  len:=lang(strName, nil, 0);
  try
    // Hier Unicode-Anpassung: jeweils 2 Byte pro Char + 2 Bytes für Stopp: \0
    GetMem(Buffer, len*2+2);

    // Hier Unicode-Anpassung: jeweils 2 Byte pro Char + 2 Bytes für Stopp: \0
    len:=lang(strName, Buffer, len*2+2);

    result:=String(Buffer);
  finally
    FreeMem(Buffer);
  end;
end;


{****** Holt einen Componentennamen aus der DLL **********}
function TForm1._cl(compName: string): String;
var
  s: String;
begin
  len:=comp(PWideChar(compName), nil, 0);
  try
    // Hier Unicode-Anpassung: jeweils 2 Byte pro Char + 2 Bytes für Stopp: \0
    GetMem(Buffer, len*2+2);

    // Hier Unicode-Anpassung: jeweils 2 Byte pro Char + 2 Bytes für Stopp: \0
    len:=comp(PWideChar(compName), Buffer, len*2+2);

    result:=String(Buffer);
  finally
    // Speicher wieder freigeben
    FreeMem(Buffer);
  end;
end;


procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  hLib := LoadLibrary('de.dll');

  // Beim Laden ist ein Fehler aufgetreten
  if hLib = 0 then
  begin
    Str(GetLastError, s);
    ShowMessage(SysErrorMessage(GetLastError));
    exit;
  end;

  //Funktion laden
  @lang := GetProcAddress(hLib, '_lang');

  //Beim Laden der Funktion ist ein Fehler aufgetreten.
  if (not Assigned(lang)) then
  begin
    Str(GetLastError, s);
    ShowMessage(SysErrorMessage(GetLastError));
    exit;
  end;

  //Funktion laden
  @comp := GetProcAddress(hLib, '_compName');

  //Beim Laden der Funktion ist ein Fehler aufgetreten.
  if (not Assigned(comp)) then
  begin
    Str(GetLastError, s);
    ShowMessage(SysErrorMessage(GetLastError));
    exit;
  end;

  //Spezielle Komponententexte ersetzen.
  for i:=0 to Form1.ComponentCount-1 do
  begin
    if (Form1.Components[i].ClassName = 'TButton') then
    begin
      (Form1.Components[i] as TButton).Caption:=_cl(Form1.Components[i].Name);
    end;
  end;

  FreeLibrary(hlib);
end;

end.
Also. Fehler treten keine auf und es funktioniert eigentlich alles wunderbar. Die Frage ist nur, ob das wirklich so richtig ist. Würde das gerne vorher wissen, bevor ich weitermache. Vielleicht hilft dieser Beitrag ja dem Einen oder Anderen.

Danke im Voraus
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:47 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