Joschua
Joschua

Reputation: 6034

Delphi Translating Strings

I'm using Delphi 2007 and I wonder how the following problem can be solved:

I have to translate AComp.Caption for example, but the string that I want to assign to the caption, often depends on some data (for example a date or a number, that gets Formatted). Therefore I have to save the data and the string in a new variable for every translation, which is really annoying.

What I want to do is something like that:

// will add the string and data to an internal list of Translator
// and will then return a DynamicString, which represents the translated value
AComp.Caption := T.NewTranslatedString("Hello %s, do you like cheese?", User)

(Note that AComp.Caption ("Hello %s..") can be changed in different methods)

When switching to another language, you would call T.TranslateAgain() and the value of all strings will be translated and, if data given, formatted again.

Is this possible or do you know another way for solving the given problem?

Thanks in advance

Additional question: Are strings normal objects, that I can subclass and add dynamic behaviour that changes the string itself in special cases?

Upvotes: 2

Views: 2531

Answers (4)

user160694
user160694

Reputation:

Delphi strings are not objects, you can't add behaviours to them. You would need to develop your own class.

The Windows way to localize applications is to get advantage of resources, that can be changed (and loading redirected) without changes to the code (no need to call special functions or add new components), and without run-time calls but to load the resource. The only disadvantage of resources is they cannot be changed easily by the end user. The Delphi 2007 standard localization tools use this approach.

Anyway there are some libraries like dxGetText (which is a port of the GNU gettext library) or TsiLang, for example that use a more "intrusive" approach, requiring changes to your code or adding components. In exchange they can simplify end-user localization.

Before developing your own localization library, I would check if one of the existing ones fits youe needs.

Note: Be aware that Delphi localization tool has significant issues that weren't fixed until XE (which I didn't test yet). See for example QC #79449. Unluckily the fix was never backported to earlier releases.

Upvotes: 3

vcldeveloper
vcldeveloper

Reputation: 7489

You can use Delphi's own translator tool. It is able to extract strings and resourcestrings from your source code and form DFM files, and gives you a graphical user interface to translate them to any language. It then creates a resource DLL for each language. The DLL containing the translated strings and DFM data. You should deploy this translation DLL with your project to the destination machine.

In your case, your strings are divided into two groups; fixed strings which do not need any further processing, and parametrized strings which need some additional data to be formatted properly. For the fixed strings, you can just type in the translation into translator tool. For parametrized strings, save each one as a resourcestring and use the resourcestring for formatting them. For example:

resourcestring
  strDoYouLikeCheese = 'Hello %s, do you like cheese?';

...

AComp.Caption := Format(strDoYouLikeCheese,[User]);

Now you can use the translator tool or any resource editor to translate the resourcestring into your desired language without the need for changing your source code or recompiling it.

Upvotes: 3

jpfollenius
jpfollenius

Reputation: 16620

You could use a dictionary to keep track of the string mappings, something like this

TTranslator = class
private
  FMappings : TDictionary <String, String>;
public
  function  Translate (const SrcStr : String) : String;
  procedure SetMapping (const SrcStr, DestStr : String);
end;

function TTranslator.Translate (const SrcStr : String) : String;
begin
  if not FMappings.TryGetValue (SrcStr, Result) then
    Result := SrcStr;
end;

procedure TTranslator.SetMapping (const SrcStr, DestStr : String);
begin
  FMappings.AddOrSetValue (SrcStr, DestStr);
end;

Translating would then be simply several calls to SetMappings. This gives you a lot of flexiblity. Anyway, you might consider using the built-in localization support or even third-party solutions.

EDIT: Just saw that you are using Delphi 2007, so you don't have TDictionary available. The idea should remain valid, just use any dictionary implementation or a list-based approach.

And to answer the other part of your question: no, strings are not normal object (actually they are not objects at all). They are special in various ways (memory management, copy-on-write behaviour) and it is not possible to subclass them. But that's not what you want anyway if I understood the question correctly.

Upvotes: 1

David Heffernan
David Heffernan

Reputation: 613441

What you want to do is to localize your application. Delphi has support for this, based around the resourcestring keyword. However, I've never done any localization myself so I recommend that you do some websearch for this topic or perhaps wait for the other experts here to supply more detailed help!

Upvotes: 2

Related Questions