Localizing
your Delphi application
The localization background
There are several reasons
for writing multilingual applications. In addition to the obvious
reason – to increase revenue and distribution of software by
entering into international markets – there are two other
convincing arguments:
Shipping one core
functionality binary for all different language versions reduces the
hassle and cost of development significantly, eliminating the need
for compilation conditions and maintenance of separate source code
for each language.
Delaying the shipment
of different language versions of your software can wreak havoc with
your customers’ deployments, delaying your revenue. Making
customers wait a few months between the release of the English
version 1.0 of an application and the German version 1.0 might not
seem like a big deal. But many customers wait until the release of
the first update to an application before deploying. Add the release
delta for the update to the release delta from the original release
and you may find you’re delaying your customers deployments a
lot longer than you first realized. Ensuring that your applications
are multilingual can help avoid this.
The most popular
approach (recommended and used by Microsoft) to localization of
Windows applications is the method usually called satellite DLLs. The
main idea behind this approach is to separate out the resources from
the source code, creating a separate resource-only DLL containing all
the localized resources for each targeted language. To access the
resources at run time, the appropriate resource DLL is loaded through
the LoadLibrary API.
Language switching can be implemented by re-loading the newly
selected resources and refreshing the client area.
It is possible to separate
the resources from the executable code completely, but then we will
have to process specially the case of failure to load the appropriate
language DLL (when only a subset of the OS languages are supported in
the application, for example). Another approach is to include the
English (or your default language) resources in the main executable
file and ship satellite DLLs for other languages.
Borland ITE
Starting with Delphi 4
Borland includes the localization toolkit called Integrated
Translation Environment (ITE). ITE uses the above mentioned approach
by creating the resources DLL's for each language you want to
translate to.
What for in this
case is made the use of the third-party products? First of all, ITE
is included only into the Enterprise edition of Delphi that is not
cheap at all. The most of third-party products for localization cost
much less. Besides, a lot of ITE users are not satisfied because of
its restrictions and bugs also. I'm not going to dwell on this
question, I just note that it is discussed from time to time in
borland.public.internationalization newsgroup.
Qualities of a Good Localization
Tool
A good localization
tool should isolate localizable resources from the rest of resources
and not display text that is not to be translated.
The tool should
automatically keep items up to date with updated native language
resources. The translators should be informed about all changes in
the native resources to be able to make corrections in the
translated resources.
It is desirable that
the tool is enabled for all Windows character sets. The tools used
to edit Arabic or Hebrew interfaces also need to support a
right-to-left oriented elements.
The translator should
be able to change the font settings of the localization tool.
Localization tool
should either hide the strings that the developer refers to those
that are not to be translated and/or make them read-only.
The tool should
display the native language strings for reference and provide an
opportunity for adding comments (it may be not obvious where a
particular string appears in the user interface).
A good localization
tool should also provide a multiple-language database for keeping of
the translations for common terms, and be able to automatically
translate portions of large files.
Localizer
The Korzh.com
company has developed the toolkit aimed to ease the life of
developers feeling restricted within the limits of one language. It
may seem strangely enough but the toolkit was named Localizer .
The product is compatible with Delphi (versions 3-6) and C++ Builder
(4,5).
Localizer allows quickly
and easily separate out the translatable elements, translate them and
get the multilanguage application ready. It may operate with
different languages including oriental.
Starting with the version
2.0 Localizer has two editions – Standard and OnFly. The first
of them is oriented to the work with satellite DLLs, the second one –
for operating with the language files in the own format and for the
"on the fly" language switching. The following description
concerns to both editions except the parts where the resource DLLs
are mentioned. See the "Translation "on the fly"
section for details about the OnFly edition.
The structure
Localizer consists of
three main parts:
Language Wizard
provides the integration with Delphi IDE, prepares the data for
translation (so-called native language file) and gives some extra
possibilities. LW is a tool for the application developer.
Language Manager is
free of charge utility that is the main tool of the translator.
Language Manager operates with the language files. It allows to
create the new file (i.e. the translation to another language), edit
the existing one, create the resource DLL on the basis of the
language file.
Localizer API –
the set of classes and functions necessary for operating with the
language files and the resource DLLs in your applications.
How does it work
There are two main
iterative phases in the usage of Localizer:
The processing of the
project for saving of the localizable resources (string properties,
constants etc.) in the native language file;
The translation
itself of all localizable resources to another language(s).
At the first phase
Language Wizard scans the project and places all resources necessary
for the localization (string properties, resource strings) into the
special native language file. After that the translator (or
the developer himself – if he is a polyglot and his work is
paid) translates the native language file into another language(s)
via Language Manager utility. At that the new language files are
created (one per language) that are the basis for the resource DLLs
creation or may be used directly in the case of OnFly edition using
(see "Translation "on the fly" section).
The resource DLLs or the
language files may be delivered together with the application or
uploaded for downloading by the users. The end user should just place
the resource DLL or the language file into the EXE file folder to
make it available for translation.
As was mentioned at the
beginning of this section the application localization process is
iterative (as well as the development process). If there was made any
changes in the application, the developer should "refresh"
the native language file and transfer the refreshed file to the
translator(s). After your translations are updated, you should
refresh the existing resource DLLs.
Delphi IDE integration
Localizer is completely
integrated into the Delphi or C++ Builder development environment.
All Language Wizard options are available through the Localizer item
in the IDE main menu.
The Project Setting
submenu opens the special dialog aimed for setting of the project
localization parameters. You may enable/disable localization for the
current project, specify the properties to be processed (Caption,
Hint etc.), indicate the native language of the project and set the
other localization options via this dialog.
After you enable the
project localization, the project is compiled, the obtained EXE (or
DLL) file is scanned and the localizable resources are placed into
the native language file named .ntv.lng (here
is the project name without extension).
The same operations are
done when you select the "Refresh Language Files" menu
item. As was mentioned before, it is necessary for the language files
refreshing in compliance with the changes was made in the project.
The special utility ("Scan
.PAS Files" menu item) helps to move the hard-coded string
constants into the resourcestring section to make their localization
possible.
For example, the code
ShowMessage(‘Hello
world’);
will be changed to
resourcestring
SHelloWorld
= ‘Hello world’;
.
. . . . . . . . .
ShowMessage(SHelloWorld);
Translating of the isolated
resources
The other important
component of Localizer is Language Manager (LM). LM is a free of
charge application aimed for translating of the native language file
created by Language Wizard to the other languages. The developer may
use it himself or pass it to the professional translator.
The native language file
is used as a project for LM. If it is opened, you can create the new
language file for any of the locales supported by your OS.
LM provides the
comfortable system of state indication, filtering and sorting.
The user determines if
s/he wants to view the proper form (unit) strings or all language
file strings.
The strings that
aren't translated (yet) have the special mark. You may, for example,
leave just untranslated strings visible not to be distracted
by the others. If some properties (constants) have changed their
values during the project updating, these strings are also got the
untranslatable status.
Initially the strings in
LM are sorted by the names of properties (constants). The user may
sort the particular language ascending or descending, at that the
sorting is carried out in accordance with the rules of the language
chosen.
The strings that are
not to be translated (i.e. URL or e-mail addresses) may be marked as
untranslatable by the developer. At that they change their
color, can not be edited and can be hidden. Naturally, the translator
can not mark the strings as untranslatable.
Each language file can be
exported (imported) to (from) the text format or to (from) XML.
Resource DLLs
Namely Language Manager is
responsible for the resource DLLs creating. Even when Language Wizard
synchronizes the DLLs, it uses LM at the background.
It looks very easy from
the point of view of the user – if the language files folder
contains the native DLL (.NTV file), the "
Create DLL " item becomes available in the "File"
menu. Select it and you get the resource DLL created.
Besides, LM can
synchronize the DLLs created before. The synchronization process
brings the existing DLLs up to date in accordance with the changes
made in the language files.
Repository
The Repository
is a multilingual dictionary that is filled in by the user
(translator) and is served for (semi) automatic translating. This
tool is especially convenient for the translators that translates
several applications with the similar interface elements.
LM choose on its own where
to put or where to take from the information when you fill or use the
repository database. It may ask the user for assistance in some
special cases.
Besides, you may edit the
repository contents directly via the proper form.
Libraries
You can translate the
third-party components resources just once and then use the results
any time. Thereto, some developers make the localized resources of
their components available in some way.
Library is a
collection of language files that contain the translation of the
resources of some package (third-party, VCL, etc.). The library
translation process is nearly the same as the usual project
translation.
To process the component
resources and create the corresponding library, use the special tool
– Library Manager.
The libraries translated
before may be applied to the current project. This process consists
in the substitution of the language files strings to the
corresponding strings of the libraries files according to the
synchronization rules. The synchronization rules (by unit/constant
name, by string ID) are set during creating of the library (via the
Library Manager tool). The libraries selected by the user are applied
to all open language files in the project (except the native one).
Applying to your application
After the project was
processed by Language Wizard, the proper language files and even (if
necessary) resource DLLs was created and translated, the natural
question is arisen – how to make it working with your
application?
The first variant –
the automatic loading of the resource DLLs.
When your application
starts up, it checks the locale of the local system. If it finds any
resource DLLs with the same name as the EXE file, it checks the
extension on those DLLs. If the extension of the resource module
matches the language and country of the system locale, your
application will use the resources in that resource module instead of
the resources in the executable. If there is not a resource module
that matches both the language and the country, your application will
try to locate a resource module that matches just the language. If
there is no resource module that matches the language, your
application will use the resources compiled with the executable.
If you want your
application to use a different resource module than the one that
matches the locale of the local system, you can set a locale override
entry in the Windows registry. Under the
HKEY_CURRENT_USER\Software\Borland\Locales key, add your
application’s path and file name as a string value and set the
data value to the extension of your resource DLLs. At startup, the
application will look for resource DLLs with this extension before
trying the system locale. Setting this registry entry allows you to
test localized versions of your application without changing the
locale on your system.
The second variant –using
the Localizer API.
The Localizer
delivery contains two specific units – LocUtils for the
Standard edition and LocOnFly for the OnFly edition. Language Wizard
automatically places the proper unit into the uses section of
your dpr file.
All you need to do for the
proper language loading at the program startup is to put the Init or
InitReg method call into dpr file before any form creating. For
instance:
uses
... , LocUtils;
.
. . . . . . . . .
begin
Localizer.Init;
Application.CreateForm(...
.
. . . . . . . . .
end.
Thereto, the units contain
the methods for the language loading, the list of available languages
obtaining, filling the menu item with the list of available languages
with the following automatic translation and the others.
Translation "on the fly"
A lot of developers prefer
to give the end user an opportunity to switch the language of the
application interface "on the fly", i.e. without restarting
of the application. Just select the menu item – and get the
application on another language. It sounds attractively, but has its
own pitfalls. The point is that Delphi puts the forms (rather dfm
files in the binary form) into the RCDATA section of the resources of
the executable file. Naturally, this section (already translated)
enters the resource DLLs. After such DLL loading it is necessary to
refresh the property values of the components of the already created
forms instances. It is possible, and Borland even gives the
corresponding example – see the ReachEdit project in the Demos
folder. The trouble, however, is that the components of the forms
refreshed in such a way loose all the values of the properties set in
run time. In other words, the forms return to the state they had in
the design time. Theoretically, it is possible to restore the lost
property values after such language switching, but in practice for
more or less complex application the restoration is hard or even
impossible.
The special edition –
Localizer OnFly – was created for solving of the described
problem.
The Localizer OnFly
developers found the way by refusing the resource DLLs approach. In
spite of this they use the language files that are created and
translated via Language Manager.
Practically nothing is
changed from the point of view of the developer. S/he just doesn't
create the resource DLLs (and, correspondingly, delivers the language
files instead of them) and uses the functions from another unit
(LocOnFly instead of LocUtils) in his/er application. At that the
code that allows to load the proper language file and change the
values of the translated properties "on the fly" is
embedded to the application.
So, which of Localizers is
preferable? It depends on the needs and restrictions of the
developer. We can prove only the advantages of each of them in
comparison to another one.
The advantages of
Localizer Standard:
it uses the standard
resource files format;
the possibility of
automatically loading of the proper language according to the system
locale;
there is no need (if
you use the automatic loading) to add any strange code to your
application – it may stay absolutely independent from the
other's errors.
The advantages of
Localizer OnFly:
the size of the
language files is essentially less than the DLL's;
it may correctly
switch the application language "o the fly";
it is possible not to
change the values of the properties that you change in the run time.
So, you have the choice.
Contact
Website:http://www.korzh.com
Product page:http://www.korzh.com/delphi/localizer
E-mail:
localizer@korzh.com
|