DKLang Localization Package Help

DKLang Localization Package

Copyright ©2002-2006 Dmitry Kann, http://www.dk-soft.org/.


Release notes

Release notes: DKLang version 3.0

This is a major update to the package.

The main novelty is complete Unicode support at design level, so package handles all language data as Unicode strings (WideString). This resulted in Unicode .dklang (and .lng) files being created and loaded.

You are strongly recommended to upgrade your DKLang Translation Editor to version 3.0 as well. This is also because of Unicode support.

The problem with constant editor in Delphi 2005+ is resolved by using a separate resource file. This requires converting your old project using constants. So, if you were using DKLang version 2.x, please carefully read Upgrading from previous versions prior to installing.

Version 3.0 introduces support for Delphi 2006, but it isn't tested yet (simply because I don't have it). I believe it should be okay though.

Further details you can find in Revision History section.

Dmitry Kann

P. S. I would be thankful if you send me translations for my examples in your native language (Unicode files only please).


Legal Info

The contents of this package are subject to the Mozilla Public License Version 1.1 (the License); you may not use this package except in compliance with the License.

Alternatively, you may redistribute this library, use and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

Software distributed under the License is distributed on an as is basis, without warranty of any kind, either express or implied. See the License for the specific language governing rights and limitations under the License.

The initial developer of the original code is Dmitry Kann, http://www.dk-soft.org/.


                          MOZILLA PUBLIC LICENSE
                                Version 1.1

                              ---------------

1. Definitions.

     1.0.1. "Commercial Use" means distribution or otherwise making the
     Covered Code available to a third party.

     1.1. "Contributor" means each entity that creates or contributes to
     the creation of Modifications.

     1.2. "Contributor Version" means the combination of the Original
     Code, prior Modifications used by a Contributor, and the Modifications
     made by that particular Contributor.

     1.3. "Covered Code" means the Original Code or Modifications or the
     combination of the Original Code and Modifications, in each case
     including portions thereof.

     1.4. "Electronic Distribution Mechanism" means a mechanism generally
     accepted in the software development community for the electronic
     transfer of data.

     1.5. "Executable" means Covered Code in any form other than Source
     Code.

     1.6. "Initial Developer" means the individual or entity identified
     as the Initial Developer in the Source Code notice required by Exhibit
     A.

     1.7. "Larger Work" means a work which combines Covered Code or
     portions thereof with code not governed by the terms of this License.

     1.8. "License" means this document.

     1.8.1. "Licensable" means having the right to grant, to the maximum
     extent possible, whether at the time of the initial grant or
     subsequently acquired, any and all of the rights conveyed herein.

     1.9. "Modifications" means any addition to or deletion from the
     substance or structure of either the Original Code or any previous
     Modifications. When Covered Code is released as a series of files, a
     Modification is:
          A. Any addition to or deletion from the contents of a file
          containing Original Code or previous Modifications.

          B. Any new file that contains any part of the Original Code or
          previous Modifications.

     1.10. "Original Code" means Source Code of computer software code
     which is described in the Source Code notice required by Exhibit A as
     Original Code, and which, at the time of its release under this
     License is not already Covered Code governed by this License.

     1.10.1. "Patent Claims" means any patent claim(s), now owned or
     hereafter acquired, including without limitation,  method, process,
     and apparatus claims, in any patent Licensable by grantor.

     1.11. "Source Code" means the preferred form of the Covered Code for
     making modifications to it, including all modules it contains, plus
     any associated interface definition files, scripts used to control
     compilation and installation of an Executable, or source code
     differential comparisons against either the Original Code or another
     well known, available Covered Code of the Contributor's choice. The
     Source Code can be in a compressed or archival form, provided the
     appropriate decompression or de-archiving software is widely available
     for no charge.

     1.12. "You" (or "Your")  means an individual or a legal entity
     exercising rights under, and complying with all of the terms of, this
     License or a future version of this License issued under Section 6.1.
     For legal entities, "You" includes any entity which controls, is
     controlled by, or is under common control with You. For purposes of
     this definition, "control" means (a) the power, direct or indirect,
     to cause the direction or management of such entity, whether by
     contract or otherwise, or (b) ownership of more than fifty percent
     (50%) of the outstanding shares or beneficial ownership of such
     entity.

2. Source Code License.

     2.1. The Initial Developer Grant.
     The Initial Developer hereby grants You a world-wide, royalty-free,
     non-exclusive license, subject to third party intellectual property
     claims:
          (a)  under intellectual property rights (other than patent or
          trademark) Licensable by Initial Developer to use, reproduce,
          modify, display, perform, sublicense and distribute the Original
          Code (or portions thereof) with or without Modifications, and/or
          as part of a Larger Work; and

          (b) under Patents Claims infringed by the making, using or
          selling of Original Code, to make, have made, use, practice,
          sell, and offer for sale, and/or otherwise dispose of the
          Original Code (or portions thereof).

          (c) the licenses granted in this Section 2.1(a) and (b) are
          effective on the date Initial Developer first distributes
          Original Code under the terms of this License.

          (d) Notwithstanding Section 2.1(b) above, no patent license is
          granted: 1) for code that You delete from the Original Code; 2)
          separate from the Original Code;  or 3) for infringements caused
          by: i) the modification of the Original Code or ii) the
          combination of the Original Code with other software or devices.

     2.2. Contributor Grant.
     Subject to third party intellectual property claims, each Contributor
     hereby grants You a world-wide, royalty-free, non-exclusive license

          (a)  under intellectual property rights (other than patent or
          trademark) Licensable by Contributor, to use, reproduce, modify,
          display, perform, sublicense and distribute the Modifications
          created by such Contributor (or portions thereof) either on an
          unmodified basis, with other Modifications, as Covered Code
          and/or as part of a Larger Work; and

          (b) under Patent Claims infringed by the making, using, or
          selling of  Modifications made by that Contributor either alone
          and/or in combination with its Contributor Version (or portions
          of such combination), to make, use, sell, offer for sale, have
          made, and/or otherwise dispose of: 1) Modifications made by that
          Contributor (or portions thereof); and 2) the combination of
          Modifications made by that Contributor with its Contributor
          Version (or portions of such combination).

          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
          effective on the date Contributor first makes Commercial Use of
          the Covered Code.

          (d)    Notwithstanding Section 2.2(b) above, no patent license is
          granted: 1) for any code that Contributor has deleted from the
          Contributor Version; 2)  separate from the Contributor Version;
          3)  for infringements caused by: i) third party modifications of
          Contributor Version or ii)  the combination of Modifications made
          by that Contributor with other software  (except as part of the
          Contributor Version) or other devices; or 4) under Patent Claims
          infringed by Covered Code in the absence of Modifications made by
          that Contributor.

3. Distribution Obligations.

     3.1. Application of License.
     The Modifications which You create or to which You contribute are
     governed by the terms of this License, including without limitation
     Section 2.2. The Source Code version of Covered Code may be
     distributed only under the terms of this License or a future version
     of this License released under Section 6.1, and You must include a
     copy of this License with every copy of the Source Code You
     distribute. You may not offer or impose any terms on any Source Code
     version that alters or restricts the applicable version of this
     License or the recipients' rights hereunder. However, You may include
     an additional document offering the additional rights described in
     Section 3.5.

     3.2. Availability of Source Code.
     Any Modification which You create or to which You contribute must be
     made available in Source Code form under the terms of this License
     either on the same media as an Executable version or via an accepted
     Electronic Distribution Mechanism to anyone to whom you made an
     Executable version available; and if made available via Electronic
     Distribution Mechanism, must remain available for at least twelve (12)
     months after the date it initially became available, or at least six
     (6) months after a subsequent version of that particular Modification
     has been made available to such recipients. You are responsible for
     ensuring that the Source Code version remains available even if the
     Electronic Distribution Mechanism is maintained by a third party.

     3.3. Description of Modifications.
     You must cause all Covered Code to which You contribute to contain a
     file documenting the changes You made to create that Covered Code and
     the date of any change. You must include a prominent statement that
     the Modification is derived, directly or indirectly, from Original
     Code provided by the Initial Developer and including the name of the
     Initial Developer in (a) the Source Code, and (b) in any notice in an
     Executable version or related documentation in which You describe the
     origin or ownership of the Covered Code.

     3.4. Intellectual Property Matters
          (a) Third Party Claims.
          If Contributor has knowledge that a license under a third party's
          intellectual property rights is required to exercise the rights
          granted by such Contributor under Sections 2.1 or 2.2,
          Contributor must include a text file with the Source Code
          distribution titled "LEGAL" which describes the claim and the
          party making the claim in sufficient detail that a recipient will
          know whom to contact. If Contributor obtains such knowledge after
          the Modification is made available as described in Section 3.2,
          Contributor shall promptly modify the LEGAL file in all copies
          Contributor makes available thereafter and shall take other steps
          (such as notifying appropriate mailing lists or newsgroups)
          reasonably calculated to inform those who received the Covered
          Code that new knowledge has been obtained.

          (b) Contributor APIs.
          If Contributor's Modifications include an application programming
          interface and Contributor has knowledge of patent licenses which
          are reasonably necessary to implement that API, Contributor must
          also include this information in the LEGAL file.

               (c)    Representations.
          Contributor represents that, except as disclosed pursuant to
          Section 3.4(a) above, Contributor believes that Contributor's
          Modifications are Contributor's original creation(s) and/or
          Contributor has sufficient rights to grant the rights conveyed by
          this License.

     3.5. Required Notices.
     You must duplicate the notice in Exhibit A in each file of the Source
     Code.  If it is not possible to put such notice in a particular Source
     Code file due to its structure, then You must include such notice in a
     location (such as a relevant directory) where a user would be likely
     to look for such a notice.  If You created one or more Modification(s)
     You may add your name as a Contributor to the notice described in
     Exhibit A.  You must also duplicate this License in any documentation
     for the Source Code where You describe recipients' rights or ownership
     rights relating to Covered Code.  You may choose to offer, and to
     charge a fee for, warranty, support, indemnity or liability
     obligations to one or more recipients of Covered Code. However, You
     may do so only on Your own behalf, and not on behalf of the Initial
     Developer or any Contributor. You must make it absolutely clear than
     any such warranty, support, indemnity or liability obligation is
     offered by You alone, and You hereby agree to indemnify the Initial
     Developer and every Contributor for any liability incurred by the
     Initial Developer or such Contributor as a result of warranty,
     support, indemnity or liability terms You offer.

     3.6. Distribution of Executable Versions.
     You may distribute Covered Code in Executable form only if the
     requirements of Section 3.1-3.5 have been met for that Covered Code,
     and if You include a notice stating that the Source Code version of
     the Covered Code is available under the terms of this License,
     including a description of how and where You have fulfilled the
     obligations of Section 3.2. The notice must be conspicuously included
     in any notice in an Executable version, related documentation or
     collateral in which You describe recipients' rights relating to the
     Covered Code. You may distribute the Executable version of Covered
     Code or ownership rights under a license of Your choice, which may
     contain terms different from this License, provided that You are in
     compliance with the terms of this License and that the license for the
     Executable version does not attempt to limit or alter the recipient's
     rights in the Source Code version from the rights set forth in this
     License. If You distribute the Executable version under a different
     license You must make it absolutely clear that any terms which differ
     from this License are offered by You alone, not by the Initial
     Developer or any Contributor. You hereby agree to indemnify the
     Initial Developer and every Contributor for any liability incurred by
     the Initial Developer or such Contributor as a result of any such
     terms You offer.

     3.7. Larger Works.
     You may create a Larger Work by combining Covered Code with other code
     not governed by the terms of this License and distribute the Larger
     Work as a single product. In such a case, You must make sure the
     requirements of this License are fulfilled for the Covered Code.

4. Inability to Comply Due to Statute or Regulation.

     If it is impossible for You to comply with any of the terms of this
     License with respect to some or all of the Covered Code due to
     statute, judicial order, or regulation then You must: (a) comply with
     the terms of this License to the maximum extent possible; and (b)
     describe the limitations and the code they affect. Such description
     must be included in the LEGAL file described in Section 3.4 and must
     be included with all distributions of the Source Code. Except to the
     extent prohibited by statute or regulation, such description must be
     sufficiently detailed for a recipient of ordinary skill to be able to
     understand it.

5. Application of this License.

     This License applies to code to which the Initial Developer has
     attached the notice in Exhibit A and to related Covered Code.

6. Versions of the License.

     6.1. New Versions.
     Netscape Communications Corporation ("Netscape") may publish revised
     and/or new versions of the License from time to time. Each version
     will be given a distinguishing version number.

     6.2. Effect of New Versions.
     Once Covered Code has been published under a particular version of the
     License, You may always continue to use it under the terms of that
     version. You may also choose to use such Covered Code under the terms
     of any subsequent version of the License published by Netscape. No one
     other than Netscape has the right to modify the terms applicable to
     Covered Code created under this License.

     6.3. Derivative Works.
     If You create or use a modified version of this License (which you may
     only do in order to apply it to code which is not already Covered Code
     governed by this License), You must (a) rename Your license so that
     the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
     "MPL", "NPL" or any confusingly similar phrase do not appear in your
     license (except to note that your license differs from this License)
     and (b) otherwise make it clear that Your version of the license
     contains terms which differ from the Mozilla Public License and
     Netscape Public License. (Filling in the name of the Initial
     Developer, Original Code or Contributor in the notice described in
     Exhibit A shall not of themselves be deemed to be modifications of
     this License.)

7. DISCLAIMER OF WARRANTY.

     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.

8. TERMINATION.

     8.1.  This License and the rights granted hereunder will terminate
     automatically if You fail to comply with terms herein and fail to cure
     such breach within 30 days of becoming aware of the breach. All
     sublicenses to the Covered Code which are properly granted shall
     survive any termination of this License. Provisions which, by their
     nature, must remain in effect beyond the termination of this License
     shall survive.

     8.2.  If You initiate litigation by asserting a patent infringement
     claim (excluding declatory judgment actions) against Initial Developer
     or a Contributor (the Initial Developer or Contributor against whom
     You file such action is referred to as "Participant")  alleging that:

     (a)  such Participant's Contributor Version directly or indirectly
     infringes any patent, then any and all rights granted by such
     Participant to You under Sections 2.1 and/or 2.2 of this License
     shall, upon 60 days notice from Participant terminate prospectively,
     unless if within 60 days after receipt of notice You either: (i)
     agree in writing to pay Participant a mutually agreeable reasonable
     royalty for Your past and future use of Modifications made by such
     Participant, or (ii) withdraw Your litigation claim with respect to
     the Contributor Version against such Participant.  If within 60 days
     of notice, a reasonable royalty and payment arrangement are not
     mutually agreed upon in writing by the parties or the litigation claim
     is not withdrawn, the rights granted by Participant to You under
     Sections 2.1 and/or 2.2 automatically terminate at the expiration of
     the 60 day notice period specified above.

     (b)  any software, hardware, or device, other than such Participant's
     Contributor Version, directly or indirectly infringes any patent, then
     any rights granted to You by such Participant under Sections 2.1(b)
     and 2.2(b) are revoked effective as of the date You first made, used,
     sold, distributed, or had made, Modifications made by that
     Participant.

     8.3.  If You assert a patent infringement claim against Participant
     alleging that such Participant's Contributor Version directly or
     indirectly infringes any patent where such claim is resolved (such as
     by license or settlement) prior to the initiation of patent
     infringement litigation, then the reasonable value of the licenses
     granted by such Participant under Sections 2.1 or 2.2 shall be taken
     into account in determining the amount or value of any payment or
     license.

     8.4.  In the event of termination under Sections 8.1 or 8.2 above,
     all end user license agreements (excluding distributors and resellers)
     which have been validly granted by You or any distributor hereunder
     prior to termination shall survive termination.

9. LIMITATION OF LIABILITY.

     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.

10. U.S. GOVERNMENT END USERS.

     The Covered Code is a "commercial item," as that term is defined in
     48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
     software" and "commercial computer software documentation," as such
     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
     all U.S. Government End Users acquire Covered Code with only those
     rights set forth herein.

11. MISCELLANEOUS.

     This License represents the complete agreement concerning subject
     matter hereof. If any provision of this License is held to be
     unenforceable, such provision shall be reformed only to the extent
     necessary to make it enforceable. This License shall be governed by
     California law provisions (except to the extent applicable law, if
     any, provides otherwise), excluding its conflict-of-law provisions.
     With respect to disputes in which at least one party is a citizen of,
     or an entity chartered or registered to do business in the United
     States of America, any litigation relating to this License shall be
     subject to the jurisdiction of the Federal Courts of the Northern
     District of California, with venue lying in Santa Clara County,
     California, with the losing party responsible for costs, including
     without limitation, court costs and reasonable attorneys' fees and
     expenses. The application of the United Nations Convention on
     Contracts for the International Sale of Goods is expressly excluded.
     Any law or regulation which provides that the language of a contract
     shall be construed against the drafter shall not apply to this
     License.

12. RESPONSIBILITY FOR CLAIMS.

     As between Initial Developer and the Contributors, each party is
     responsible for claims and damages arising, directly or indirectly,
     out of its utilization of rights under this License and You agree to
     work with Initial Developer and Contributors to distribute such
     responsibility on an equitable basis. Nothing herein is intended or
     shall be deemed to constitute any admission of liability.

13. MULTIPLE-LICENSED CODE.

     Initial Developer may designate portions of the Covered Code as
     "Multiple-Licensed".  "Multiple-Licensed" means that the Initial
     Developer permits you to utilize portions of the Covered Code under
     Your choice of the NPL or the alternative licenses, if any, specified
     by the Initial Developer in the file described in Exhibit A.

EXHIBIT A -Mozilla Public License.

     ``The contents of this file are subject to the Mozilla Public License
     Version 1.1 (the "License"); you may not use this file except in
     compliance with the License. You may obtain a copy of the License at
     http://www.mozilla.org/MPL/

     Software distributed under the License is distributed on an "AS IS"
     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
     License for the specific language governing rights and limitations
     under the License.

     The Original Code is ______________________________________.

     The Initial Developer of the Original Code is ________________________.
     Portions created by ______________________ are Copyright (C) ______
     _______________________. All Rights Reserved.

     Contributor(s): ______________________________________.

     Alternatively, the contents of this file may be used under the terms
     of the _____ license (the  "[___] License"), in which case the
     provisions of [______] License are applicable instead of those
     above.  If you wish to allow use of your version of this file only
     under the terms of the [____] License and not to allow others to use
     your version of this file under the MPL, indicate your decision by
     deleting  the provisions above and replace  them with the notice and
     other provisions required by the [___] License.  If you do not delete
     the provisions above, a recipient may use your version of this file
     under either the MPL or the [___] License."

     [NOTE: The text of this Exhibit A may differ slightly from the text of
     the notices in the Source Code files of the Original Code. You should
     use the text of this Exhibit A rather than the text found in the
     Original Code Source Code for Your Modifications.]


          GNU LESSER GENERAL PUBLIC LICENSE
               Version 2.1, February 1999

 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

[This is the first released version of the Lesser GPL.  It also counts
 as the successor of the GNU Library Public License, version 2, hence
 the version number 2.1.]

                Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.

  This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it.  You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.

  When we speak of free software, we are referring to freedom of use,
not price.  Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.

  To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights.  These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.

  For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you.  You must make sure that they, too, receive or can get the source
code.  If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it.  And you must show them these terms so they know their rights.

  We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.

  To protect each distributor, we want to make it very clear that
there is no warranty for the free library.  Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.

  Finally, software patents pose a constant threat to the existence of
any free program.  We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder.  Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.

  Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License.  This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License.  We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.

  When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library.  The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom.  The Lesser General
Public License permits more lax criteria for linking other code with
the library.

  We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License.  It also provides other free software developers Less
of an advantage over competing non-free programs.  These disadvantages
are the reason we use the ordinary General Public License for many
libraries.  However, the Lesser license provides advantages in certain
special circumstances.

  For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard.  To achieve this, non-free programs must be
allowed to use the library.  A more frequent case is that a free
library does the same job as widely used non-free libraries.  In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.

  In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software.  For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.

  Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.

  The precise terms and conditions for copying, distribution and
modification follow.  Pay close attention to the difference between a
"work based on the library" and a "work that uses the library".  The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.

          GNU LESSER GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".

  A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.

  The "Library", below, refers to any such software library or work
which has been distributed under these terms.  A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language.  (Hereinafter, translation is
included without limitation in the term "modification".)

  "Source code" for a work means the preferred form of the work for
making modifications to it.  For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.

  Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it).  Whether that is true depends on what the Library does
and what the program that uses the Library does.

  1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.

  You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.

  2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

    a) The modified work must itself be a software library.

    b) You must cause the files modified to carry prominent notices
    stating that you changed the files and the date of any change.

    c) You must cause the whole of the work to be licensed at no
    charge to all third parties under the terms of this License.

    d) If a facility in the modified Library refers to a function or a
    table of data to be supplied by an application program that uses
    the facility, other than as an argument passed when the facility
    is invoked, then you must make a good faith effort to ensure that,
    in the event an application does not supply such function or
    table, the facility still operates, and performs whatever part of
    its purpose remains meaningful.

    (For example, a function in a library to compute square roots has
    a purpose that is entirely well-defined independent of the
    application.  Therefore, Subsection 2d requires that any
    application-supplied function or table used by this function must
    be optional: if the application does not supply it, the square
    root function must still compute square roots.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.

In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

  3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library.  To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License.  (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.)  Do not make any other change in
these notices.

  Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.

  This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.

  4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.

  If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.

  5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library".  Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.

  However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library".  The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.

  When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library.  The
threshold for this to be true is not precisely defined by law.

  If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work.  (Executables containing this object code plus portions of the
Library will still fall under Section 6.)

  Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.

  6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.

  You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License.  You must supply a copy of this License.  If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License.  Also, you must do one
of these things:

    a) Accompany the work with the complete corresponding
    machine-readable source code for the Library including whatever
    changes were used in the work (which must be distributed under
    Sections 1 and 2 above); and, if the work is an executable linked
    with the Library, with the complete machine-readable "work that
    uses the Library", as object code and/or source code, so that the
    user can modify the Library and then relink to produce a modified
    executable containing the modified Library.  (It is understood
    that the user who changes the contents of definitions files in the
    Library will not necessarily be able to recompile the application
    to use the modified definitions.)

    b) Use a suitable shared library mechanism for linking with the
    Library.  A suitable mechanism is one that (1) uses at run time a
    copy of the library already present on the user's computer system,
    rather than copying library functions into the executable, and (2)
    will operate properly with a modified version of the library, if
    the user installs one, as long as the modified version is
    interface-compatible with the version that the work was made with.

    c) Accompany the work with a written offer, valid for at
    least three years, to give the same user the materials
    specified in Subsection 6a, above, for a charge no more
    than the cost of performing this distribution.

    d) If distribution of the work is made by offering access to copy
    from a designated place, offer equivalent access to copy the above
    specified materials from the same place.

    e) Verify that the user has already received a copy of these
    materials or that you have already sent this user a copy.

  For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it.  However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.

  It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system.  Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.

  7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:

    a) Accompany the combined library with a copy of the same work
    based on the Library, uncombined with any other library
    facilities.  This must be distributed under the terms of the
    Sections above.

    b) Give prominent notice with the combined library of the fact
    that part of it is a work based on the Library, and explaining
    where to find the accompanying uncombined form of the same work.

  8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License.  Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License.  However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.

  9. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Library or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.

  10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.

  11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all.  For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.

If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded.  In such case, this License incorporates the limitation as if
written in the body of this License.

  13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number.  If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation.  If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.

  14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission.  For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this.  Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.

                NO WARRANTY

  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.

             END OF TERMS AND CONDITIONS

           How to Apply These Terms to Your New Libraries

  If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change.  You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).

  To apply these terms, attach the following notices to the library.  It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.

    <one line to give the library's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

Also add information on how to contact you by electronic and paper mail.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary.  Here is a sample; alter the names:

  Yoyodyne, Inc., hereby disclaims all copyright interest in the
  library `Frob' (a library for tweaking knobs) written by James Random Hacker.

  <signature of Ty Coon>, 1 April 1990
  Ty Coon, President of Vice

That's all there is to it!


General Description

DKLang Localization Package is a set of classes intended to simplify localization of applications written in Delphi.

What are the benefits of DKLang compared to Borland's ITE (Integrated Translation Environment)?

  • First, DKLang is completely free while ITE is only supplied with Delphi Enterprise Edition. Moreover, DKLang is open-source so you always can see 'how the wind blows'.
  • Second, DKLang is very lightweight and runtime-optimized. You always get predictable results as the implemented technology is obvious and transparent.
  • Third, DKLang allows transparent language switching at any time while ITE relies on a resource DLL with predefined extension when loading the program and you cannot change the language further.
  • Fourth, Application using DKLang can consist of the only executable which includes any number of languages in its resource; it allows you to decide yourself which language should be included 'statically' and which ones are linked when program runs. In contrast, ITE always requires that a DLL with predefined extension for each language resides in the program directory: this means you should redistribute all the language DLLs with each copy of the program.
  • And finally, language files are plain-text files so one can edit them with any text editor supporting Unicode. ITE uses only compiled resource DLLs prepared with using special Translation Manager.


Package Features

  • Ease of use. Put a TDKLanguageController on the form, save the project (this will automatically create a language source file) and add a couple of lines to program code: you get a functional multilanguage application! See the included examples to learn the details.
  • Full integration with Delphi VCL component library. A possibility of automated change tracking in structure or properties of forms, frames, data modules etc., and owned components.
  • Complete Unicode support (on a robust basement of Tnt Delphi Unicode Controls).
  • Storing property values for String (AnsiString), ShortString and WideString properties. Storing property values of class TStrings, TWideStrings, TCollection item properties and property values of TPersistent descendants. Only the properties recognized by Delphi streaming mechanism as stored are processed to avoid storing excessive data.
  • A possibility for defining a set of string constants for a project. A constant is referred to by its name (binary name search is implemented). See the Constants Example.
  • Storing translations in plain-text (ANSI or Unicode) files, which can be edited with any text editor. However, there's a much more convenient tool available for creating the translations, DKLang Translation Editor.
  • Synchronous language switching in all displayed forms by changing the current language of global TDKLanguageManager instance.
  • Events fired in a non-visual component just before and after the language change.
  • A possibility for ignoring any properties, as well as a list of forcibly stored properties recognized as not stored. Both lists are formed using name masks (eg, *.Font.Name).
  • Automated saving the localization data for the whole project into a so-called language source file (a file having .dklang extension).
  • A possibility of using the localization mechanism when no visual forms instantiated (for localizing constants only). A possibility of building the project with DKLang runtime package.
  • A thread-safe design allowing for proper functioning in multithreaded environment. This allows non-blocking data read access with a number of threads at once.

Read Technology And Background section to learn the details.


Technology And Background

VCL integration

The package introduces a non-visual VCL component called TDKLanguageController, which is to be placed on each form you wish to localize. Language controller automatically maintains an internal list of all components and their properties of type String (also known as AnsiString or long string), ShortString and WideString (complete Unicode support is implemented). There's a little chance you will ever need another type of data to be changed in synch with language change.

So, the language controller keeps a list of component properties, each having assigned a form-wide unique natural number identifier (ID). This is done transparently by the controller so you don't need to bother when you add or remove components to/from the form, or change their property values.

Additionally, if a controller's Options include dklcoAutoSaveLangSource (this is the default), the controller saves its data in a plain text file (starting with version 3.0 of the package the file encoding is Unicode) into the so-called project language source, each time you save modifications to the form the controller is on. The project language source is a file named the same as the project (.dpr) file, but having .dklang extension. Each controller replaces the corresponding section in that file when it saves its data. If autosave is off you are still able to save the controller data by right-clicking the component on the form and selecting the Save data to project language source item. You may also select the Project | Update project language source main menu item, this will force all the contollers available for the project to update their language source in project's .dklang file.

Language Manager

The package also introduces TDKLanguageManager class an instance of which is accessible via global function LangManager. The manager is instantiated first time the function is called. This will happen once a form having a controller will be instantiated, or when you invoke the LangManager e. g. to scan for language files (see the provided examples). Language manager performs all tasks of maintaining the list of available languages or switching between them.

Understanding constants

Constants are often used to display messages, titles, labels etc. in language that should match the program language. DKLang offers a simple yet functional solution of implementing constants.

You define a set of constants in the default language of your project using Project | Edit project constants... IDE menu item (a project must be open in IDE). This opens DKLang Constant Editor dialog allowing you to review, edit, add or remove constants.

In order to link constant resource file to your project add the following line to project source file (.dpr):

{$R *.dkl_const.res}

A constant entry consists of a name and a value.
Constant name must meet the standard Delphi identifier naming requirements, i. e. consist of alphanumric, digit and underscore characters only and not start with a digit; the name must be unique (case makes no sense) over the whole list.
Constant value is a WideString (Unicode) value which can also be empty.

To read value of a constant you use its name (again, case-insensitively) and obtain an Unicode (original) or ANSI value (converted from Unicode using appropriate code pade) using these functions:

DKLangConstW('MyConstant') // Unicode
DKLangConstA('MyConstant') // ANSI

Making a translation

You may use freeware DKLang Translation Editor application to open the language source files (.dklang), and to create new translations (.lng files) based on them.

NB: Do not edit .dklang files directly since the contents of these files is controlled automatically by language controllers and constant editor. Any changes to property mappings or constant values will be lost once the file is updated!
Nevertheless, you can add your custom comments (each line starting with a semicolon) at the top of the file. The package leaves such comments intact.


Requirements

The Package was designed for the following versions of Borland IDE (all with the latest updates applied):

  • Delphi 6
  • Delphi 7
  • BDS 2005
  • BDS 2006 (didn't tested yet)

DKLang Localization Package requires Tnt Delphi Unicode Controls by Troy Wolbrink. You can freely download and install Tnt Controls package from http://www.tntware.com/.

Tnt Controls package is necessary for both runtime and designtime parts of DKLang.


Issues/Drawbacks

  • The implemented localization mechanism doesn't support VFI (visual form inheritance). It is recommended to put language controller onto a final, derived form, and not onto the common ancestor form, since there's no means to track the origin of a property value.
  • No support for custom-defined properties implemented (ie. ones defined with DefineProperties() method). Implementing such a feature would require knowing and analyzing all the form (visual) ancestors, which is a somewhat hard task.
  • You cannot properly handle the forms open in the IDE as standalone files. DKLang package requires that you have an active project open.


Installation

  1. Unpack the package files into a directory.
  2. Start Delphi IDE.
  3. Open Packages\dklangN.dpk (where N is your Delphi version: 6 for Delphi 6, 7 for Delphi 7, 9 for BDS 2005, 10 for BDS 2006) and click Compile.
  4. Open Packages\dcldklangN.dpk (where N is again your Delphi version), click Compile, then click Install.
  5. Close the files (don't save the changes if any).
  6. Add the path to DKLang.pas to the IDE library path.

Notice that both compiled packages (dklangN.bpl and dcldklangN.bpl) must reside in a directory listed in system PATH (usually packages are compiled to ...\Borland\DelphiN\Projects\Bpl (Delphi 6 and 7) or personal folder\Borland Studio Projects\Bpl (Delphi 8+)).

If you're upgrading: don't forget to read Upgrading from previous versions section.


Upgrading from previous versions

Upgrading from 2.x

The following moments should be considered:

  1. DKLang starting with version 3.0 outputs language source files (.dklang) solely in Unicode. It is also preferable to use Unicode translation files (.lng) as well, but the package still can read ANSI files produced by version 2.x. It uses LANGID parameter value to properly convert file contents into Unicode, so loading a translation takes a bit longer because the loading occurs twice (first time to determine the language ID, and second time to load the file with a correct code page).
    To be able to load Unicode .dklang and save Unicode .lng files you have to upgrade DKLang Translation Editor to version 3.0 or later (if available). The program will warn you if you will try to save ANSI translation based on an Unicode source, and vice versa.
  2. DKLang starting with version 3.0 stores constants in a separate resource file (project_name.dkl_const.res) instead of project resource file (project_name.res). This allows editing constants in Delphi 2005 and later thus overcoming inaccessibility of project resource interface (IOTAProjectResource) in those IDEs (this bug was introduced in BDS 2005 and still persists in BDS 2006).
    If you were using DKLang 2.x constants, you should convert all your projects using the Converter, and add the following line to project source files (.dpr):
    {$R *.dkl_const.res}

Converter from 2.x

File: Converter_v2\DKLang_Converter_v2.dpr

Compile the converter using your IDE (most recent DKLang version must be installed before) and use it to split project resource file project_name.res to DKLang constant resource file project_name.dkl_const.res, and optionally to remove constant resources from the project file (you must remove it or duplicate resource name will be reported).

You can also download a precompiled Converter executable.


Package Contents

DKLang.pas | A package source file
DKLangReg.dcr | A package source file
DKLangReg.pas | A package source file
DKL_ConstEditor.dfm | A package source file
DKL_ConstEditor.pas | A package source file
DKL_Expt.pas | A package source file
dklang.chm | This help file
Converter_v2/ | Converter for upgrading from version 2.x (source files)
Examples/ | Demo projects
Packages/ | Package files


Revision History

DKLang 3.01
[Aug 22, 2006]
  • Updated for BDS 2006 compatibility, thanks to Robert Lee.
DKLang 3.0
[Aug 08, 2006]
  • The package is rewritten to implement full Unicode support; initial Unicode-enabled version is developed by Bruce J. Miller:
    • String values became WideString (component property values, constants and all others except component, property and constant names).
    • Added new TDKLanguageManager properties: CodePage, ConstantValueA[], ConstantValueW[].
    • Added new TDKLanguageController options: dklcoIgnoreNonAlphaProps (ignore all properties with no alpha characters), dklcoIgnoreFontProps (ignore all TFont properties).
    • Added new global functions for retrieving constant values: DKLangConstW(), DKLangConstA().
    • Removed function GetLangIDName(); WideGetLocaleStr() should be used instead.
  • Constants are no longer stored in project resource file (.res). Instead, they are stored in a separate resource file (.dkl_const.res).
  • New examples: Ansi, Notepad.
  • Converted all readme files into single .chm including API reference.
  • Added support for BDS 2006.
DKLang 2.4
[Jun 23, 2005]
  • Added property TDKLanguageController.SectionName which allows customizing section which stores language data.
  • Added properties TDKLanguageManager.LanguageIndex, TDKLanguageManager.LanguageResources[].
  • Bug fix: TDKLanguageManager.IndexOfLanguageID() returned value less by 1 than correct value for non-default languages.
  • New examples: Frames, MDI, Resource.
DKLang 2.3
[Dec 21, 2004]
  • DKLang now uses a double licensing system. You may use, modify or redistribute it either under Mozilla Public License 1.1, or under GNU Lesser General Public License 2.1 terms. In particular, this means the library can be used in any GPL-licensed application or library.
  • Fixed dcldklang* installation problem under non-English versions of Delphi.
DKLang 2.2
[Nov 27, 2004]
  • Added support for Delphi 2005.
  • Changed the order of applying a language: first constants are updated, then controllers. This allows to read correct constant values in controllers' OnLanguageChanged event handlers.
DKLang 2.1
[Sep 26, 2004] 		The first public release (all prior versions were only for private use).


Contributors

The initial Unicode-enabled version of DKLang was developed by Bruce J. Miller.

DKLang uses Unicode support routines and classes from Tnt Delphi Unicode Controls by Troy Wolbrink.


Banners

You can use these banners to indicate that your application has been localized with DKLang, and thus promote the package.

Click a banner to view the code:

DKLang: an opensource localization package for Delphi DKLang: an opensource localization package for Delphi

Banner code:


Supplied Examples

The following examples are included with this package:

  • Simple
  • Ansi
  • Constants
  • Resource
  • MDI
  • Frames
  • Notepad


Simple Example

File: Examples\Simple\DKLang_Simple_Demo.dpr

This is a most simple example on how DKLang Package works. Only GUI elements are localized in this example.

Notice that in contrast with Ansi Example all controls used are Unicode-aware controls (Tnt controls), so on an Unicode-enabled platform (NT, 2000 or XP) they will correctly display any language (provided system font has an appropriate code page).


Ansi Example

File: Examples\Ansi\DKLang_Ansi_Demo.dpr

This example resembles Simple one except that it uses only conventional VCL controls instead of Tnt Unicode Controls so it can't correcty display any interface language with character set other than currently set default for non-Unicode programs.

Notice that the following line causes implicit Unicode-to-ANSI conversion:

cbLanguage.Items.Add(LangManager.LanguageNames[i]);

This is because LangManager.LanguageNames[] returns a WideString while cbLanguage.Items.Add() takes an AnsiString as an argument. Implicit WideString to AnsiString and back conversions always use system default code page set for Unicode-unaware software (configured in Regional Settings application of Control Panel). This is the best what we might do here because language names returned by LangManager.LanguageNames[] are also taken from the system, being produced in the current interface language. There's a good chance this language is the same as language being used for non-Unicode programs, but if they differ, we again can't ensure language list is displayed correctly.


Constants Example

File: Examples\Constants\DKLang_Constants_Demo.dpr

This is a little bit more advanced example on DKLang Package usage.

When you click the Test button, a message box is displayed, with the text taken from a constant. You can edit the project constants ONLY by using Project | Edit project constants... menu item. Don't edit the .dklang file directly as its contents is generated and updated automatically!

Notice constant resource link directive in the project source file (.dpr):

{$R *.dkl_const.res}


Resource Example

File: Examples\Resource\DKLang_Resource_Demo.dpr

This is an example on using DKLang Package with language files built in application's resources.

The supplied LangFiles.rc file is a source resource script. Being compiled with Borland Resource Compiler, brcc32.exe (found in Delphi's Bin directory), it produces a corresponding resource binary, LangFiles.res.

The latter is linked into the application using the $R directive located at Main.pas.

Note that you can also keep using the conventional method of scanning for .lng files in conjunction with having some language files residing in the executable's resources.


MDI Example

File: Examples\MDI\DKLang_MDI_Demo.dpr

This is a simple example on using DKLang Package in an MDI application. While it seems to be a quite general task, there's a trick to make it live.

The point is that each MDI child is created owned by the parent form (fMain). VCL requires that all owned components have unique names across their owner, so you would never be able to have two (or more) instances of a form owned by fMain if they aren't renamed.

VCL offers a cheap solution for this: it renames the second instance of fMDIChild to fMDIChild_1, third to fMDIChild_2 and so on.

But we want all of the forms being translated from the same section of the language file, don't we? So our answer to VCL's behaviour is that we set fMDIChild.lcMain.SectionName to 'fMDIChild', and now that works.


Frames Example

File: Examples\Frames\DKLang_Frames_Demo.dpr

This is a basic example on how you use frames with DKLang Package. The three frames are translated from a single language file section. This is achieved by assigning the SectionName property in the base frame class (TfrFontSettings) so all three its descendants (inlined in the main form) also have the same value for SectionName. This way all tree frames are associated with the same translation.

This is only one of four possible methods of translating frames.

The second method would use empty value for SectionName thus causing the section to bear name frFontSettings; for the inlined frame to be translated automatically, the frame component should be named the same, ie. frFontSettings. Obviously, this allows for having only one instance of a frame on a form.

The third method assumes you turn off autosaving (exclude dklcoAutoSaveLangSource from lcMain.Options) in the base frame class, but turning it back on in the inlined descendant frames. This way you can have several frame instances on a form, but each frame is translated separately. Do not forget to exclude frame properties from form's language controller (inspect this fMain.lcMain.IgnoreList to learn how you do it).

And finally you can have no controller at all in the base frame, but rather serve all the form component hierarchy, including inlined frames' components, with the only form's controller. This way you also can have several frame instances with each property translated separately.

It's up to you to decide which method is more suitable for your needs; you can use different methods in a project.

Also this example demonstrates project constants usage.


Notepad Example

File: Examples\Simple\DKLang_Notepad_Demo.dpr

This is a more functional example of a localizable application written in the spirit of Windows Notepad.


Unit Reference

List of DKLang API units in alphabetical order - Type Index

Unit | Size | Description
DKL_ConstEditor C1 | 15531 | Designtime project constant editor dialog declaration
DKL_Expt C4 | 19386 | Declarations of the core IDE integration component - DKLang Expert
DKL_ResFile C2 R2 P2 | 14781 | Routines and classes to handle .res resource files. WARNING: TDKLang_ResFile only handles 32-bit resource files and does not support 16-bit ones!
DKLang I1 C11 R4 P4 | 109646 | The main unit (and the only required runtime unit) of the package. Contains all the basic class and component declarations
DKLangReg | 2379 | Component, expert and component editor registration routines


DKL_ConstEditor

DKLang API / DKL_ConstEditor unit

Designtime project constant editor dialog declaration
Size: 15531

Classes
TdDKL_ConstEditor = class(TForm)


DKL_ConstEditor / TdDKL_ConstEditor

DKLang API / DKL_ConstEditor / TdDKL_ConstEditor class

procedure bEraseClick(Sender: TObject); |
procedure bLoadClick(Sender: TObject); |
procedure bOKClick(Sender: TObject); |
procedure bSaveClick(Sender: TObject); |
procedure CheckEntryIndexValidity(iIndex: Integer); | Raises an exception if entry (constant) index is not valid
procedure CheckNamesValid; | Raises an exception if constant names are not valid (includes uniqueness checking)
procedure DeleteEntry(iIndex: Integer); | Deletes the specified entry
procedure DoClose(var Action: TCloseAction); override; |
procedure DoShow; override; |
procedure EnsureVirtualRowExists; | Ensures a virtual row is available at the end of the table
property EntryCount: Integer read GetEntryCount write SetEntryCount; | Entry (constant) count
property EntryNames[Index: Integer]: String read GetEntryNames write SetEntryNames; | Constant names by index
property EntryValues[Index: Integer; bEncoded: Boolean]: WideString read GetEntryValues write SetEntryValues; | Constant names by index. If bEncoded=True, the constant value is represented 'encoded', with no literal control chars; if bEncoded=False, the value is represented 'as is', with linebreaks, tabs, etc. in it
function GetEntryCount: Integer; |
function GetEntryNames(Index: Integer): String; |
function GetEntryValues(Index: Integer; bEncoded: Boolean): WideString; |
procedure gMainKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); |
procedure gMainMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); |
procedure gMainSelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); |
procedure InitializeDialog(AConsts: TDKLang_Constants ; bEraseAllowed: Boolean); | Initializes the dialog
function IsRowEmpty(iRow: Integer): Boolean; | Returns True if the specified row has neither name nor value
procedure LoadSettings; |
procedure Resize; override; |
procedure SaveSettings; | Storing/restoring the settings
procedure SetEntryCount(iCount: Integer); |
procedure SetEntryNames(Index: Integer; const sValue: String); |
procedure SetEntryValues(Index: Integer; bEncoded: Boolean; const wsValue: WideString); |
procedure UpdateCount; | Updates the count info
procedure UpdateGridColumnWidths; | Updates gMain columns' widths so that they both fit into the client area


DKL_Expt

DKLang API / DKL_Expt unit

Declarations of the core IDE integration component - DKLang Expert
Size: 19386

Classes
TDKLang_Expert = class(TNotifierObject, IOTAWizard) | TDKLang_Expert
TDKLang_FormNotifier = class(TNotifierObject, IOTANotifier, IOTAFormNotifier) | TDKLang_FormNotifier
TDKLang_OTAIDENotifier = class(TNotifierObject, IOTAIDENotifier) | TDKLang_OTAIDENotifier
TDKLangControllerEditor = class(TComponentEditor) | TDKLanguageController component editor


DKL_Expt / TDKLang_Expert

DKLang API / DKL_Expt / TDKLang_Expert class

TDKLang_Expert

function EditConstantsResource: Boolean; | Invokes the constant editor for editing constant data in the project resources. Returns True if user saved the changes
procedure Execute; |
function GetIDString: string; | IOTAWizard
function GetLangIDCallback: LANGID; | Callback function for obtaining current language ID
function GetName: string; |
function GetState: TWizardState; |
procedure ItemClick_EditConstants(Sender: TObject); |
procedure ItemClick_UpdateLangSource(Sender: TObject); |
function NewMenuItem(const sCaption: String; Menu: TMenuItem; AOnClick: TNotifyEvent): TMenuItem; | Adds and returns a menu item


DKL_Expt / TDKLang_FormNotifier

DKLang API / DKL_Expt / TDKLang_FormNotifier class

TDKLang_FormNotifier

procedure ComponentRenamed(ComponentHandle: TOTAHandle; const OldName, NewName: String); |
procedure Destroyed; | IOTANotifier
procedure FormActivated; | IOTAFormNotifier
procedure FormSaving; |


DKL_Expt / TDKLang_OTAIDENotifier

DKLang API / DKL_Expt / TDKLang_OTAIDENotifier class

TDKLang_OTAIDENotifier

procedure AfterCompile(Succeeded: Boolean); |
procedure BeforeCompile(const Project: IOTAProject; var Cancel: Boolean); |
procedure FileNotification(NotifyCode: TOTAFileNotification; const FileName: string; var Cancel: Boolean); | IOTAIDENotifier


DKL_Expt / TDKLangControllerEditor

DKLang API / DKL_Expt / TDKLangControllerEditor class

TDKLanguageController component editor

procedure ExecuteVerb(Index: Integer); override;
function GetVerb(Index: Integer): string; override;
function GetVerbCount: Integer; override;


DKL_ResFile

DKLang API / DKL_ResFile unit

Routines and classes to handle .res resource files. WARNING: TDKLang_ResFile only handles 32-bit resource files and does not support 16-bit ones!
Size: 14781

Classes
TDKLang_ResEntry = class(TObject) | Single resource entry
TDKLang_ResFile = class(TObject) |
Records
TResResourceEntryHeader = packed record
TResResourceEntryProps = packed record
Pointers
PResResourceEntryHeader = ^TResResourceEntryHeader | Resource entry header
PResResourceEntryProps = ^TResResourceEntryProps | Resource entry properties


DKL_ResFile / PResResourceEntryHeader

DKLang API / DKL_ResFile / PResResourceEntryHeader pointer

Resource entry header


DKL_ResFile / PResResourceEntryProps

DKLang API / DKL_ResFile / PResResourceEntryProps pointer

Resource entry properties


DKL_ResFile / TDKLang_ResEntry

DKLang API / DKL_ResFile / TDKLang_ResEntry class

Single resource entry

property Characteristics: Cardinal read FCharacteristics write FCharacteristics; | Characteristics
function Clone: TDKLang_ResEntry ; | Creates and returns an exact copy of the entry
property DataVersion: Cardinal read FDataVersion write FDataVersion; | Data version
property Language: LANGID read FLanguage write FLanguage; | Language
property MemoryFlags: Word read FMemoryFlags write FMemoryFlags; | Memory flags
property Name: WideString read FName write FName; | Entry name
property RawData: String read FRawData write FRawData; | Raw (unparsed) entry data
property ResType: WideString read FResType write FResType; | Entry resource type
procedure SaveToStream(Stream: TStream); | Stores resource entry into the stream
property Version: Cardinal read FVersion write FVersion; | Version


DKL_ResFile / TDKLang_ResFile

DKLang API / DKL_ResFile / TDKLang_ResFile class

function AddEntry(Item: TDKLang_ResEntry ): Integer; | Adds an entry and returns its index
procedure ClearEntries; | Clears the entry list
procedure DeleteEntry(Index: Integer); | Deletes the entry
property Entries[Index: Integer]: TDKLang_ResEntry read GetEntries; default; | Entries by index
property EntryCount: Integer read GetEntryCount; | Entry count
function FindEntry(const wsType, wsName: WideString): TDKLang_ResEntry ; | Tries to find an entry by its type and name. Returns nil if not found
function GetEntries(Index: Integer): TDKLang_ResEntry ; |
function GetEntryCount: Integer; |
procedure LoadFromFile(const wsFileName: WideString); | Loads .res file contents from the file
procedure LoadFromStream(Stream: TStream); | Loads .res file contents from the stream
function RemoveEntry(Item: TDKLang_ResEntry ): Integer; | Removes the entry and returns index it had before the deletion
procedure SaveToFile(const wsFileName: WideString); | Saves .res file contents into the file
procedure SaveToStream(Stream: TStream); | Saves .res file contents into the stream


DKL_ResFile / TResResourceEntryHeader

DKLang API / DKL_ResFile / TResResourceEntryHeader record

iDataSize: Integer | Data size in bytes
iHeaderSize: Integer | Header size in bytes


DKL_ResFile / TResResourceEntryProps

DKLang API / DKL_ResFile / TResResourceEntryProps record

cCharacteristics: Cardinal
cDataVersion: Cardinal
cVersion: Cardinal
wLanguage: LANGID
wMemoryFlags: Word


DKLang

DKLang API / DKLang unit

The main unit (and the only required runtime unit) of the package. Contains all the basic class and component declarations
Size: 109646

Interfaces
IDKLang_LanguageSourceObject = interface(IInterface) An interface to an object capable of storing its data as a language source strings
Classes
EDKLangError = class(Exception) | Error
TDKLang_CompEntries = class(TList) | List of component entries
TDKLang_CompEntry = class(TObject) |
TDKLang_CompTranslation = class(TList) | List of property value translations for the whole component hierarchy (usually for a single form); a plain list indexed (and sorted) by ID
TDKLang_CompTranslations = class(TList) | List of component translations
TDKLang_Constants = class(TList, IInterface, IDKLang_LanguageSourceObject) |
TDKLang_LangResources = class(TList) |
TDKLang_MaskList = class(TObjectList) | A list of masks capable of testing an arbitrary string for matching. A string is considered matching when it matches any mask from the list
TDKLang_PropEntries = class(TList) | List of property entries (sorted by property name, case-insensitively)
TDKLanguageController = class(TComponent, IDKLang_LanguageSourceObject) |
TDKLanguageManager = class(TObject) | Global thread-safe language manager class
Records
TDKLang_Constant = record
TDKLang_LangResource = record
TDKLang_PropEntry = record
TDKLang_PropValueTranslation = record
Pointers
PDKLang_Constant = ^TDKLang_Constant | A constant
PDKLang_LangResource = ^TDKLang_LangResource |
PDKLang_PropEntry = ^TDKLang_PropEntry | A single component property entry
PDKLang_PropValueTranslation = ^TDKLang_PropValueTranslation | A single component property value translation, referred to by ID


DKLang / EDKLangError

DKLang API / DKLang / EDKLangError class

Error


DKLang / IDKLang_LanguageSourceObject

DKLang API / DKLang / IDKLang_LanguageSourceObject interface

An interface to an object capable of storing its data as a language source strings

function CanStore: Boolean; | Is called just before storing begins. Must return True to allow the storing or False otherwise
function GetSectionName: WideString; |
property SectionName: WideString read GetSectionName; | The name of the section corresponding to object language source data (without square brackets)
procedure StoreLangSource(Strings: TWideStrings; StateFilter: TDKLang_TranslationStates); | Must append the language source lines (Strings) with its own data. If an entry states intersect with StateFilter, the entry should be skipped


DKLang / PDKLang_Constant

DKLang API / DKLang / PDKLang_Constant pointer

A constant


DKLang / PDKLang_LangResource

DKLang API / DKLang / PDKLang_LangResource pointer

DKLang unit - contents - type index


DKLang / PDKLang_PropEntry

DKLang API / DKLang / PDKLang_PropEntry pointer

A single component property entry


DKLang / PDKLang_PropValueTranslation

DKLang API / DKLang / PDKLang_PropValueTranslation pointer

A single component property value translation, referred to by ID


DKLang / TDKLang_CompEntries

DKLang API / DKLang / TDKLang_CompEntries class

List of component entries

function Add(Item: TDKLang_CompEntry ): Integer; | Add an entry into the list; returns the index of the newly added entry
function FindComponent(CompReference: TComponent): TDKLang_CompEntry ; | Returns entry for given component reference; nil if not found
function GetItems(Index: Integer): TDKLang_CompEntry ; |
function IndexOfCompName(const sCompName: String): Integer; | Returns index of entry by component name; -1 if not found
function IndexOfComponent(CompReference: TComponent): Integer; | Returns index of entry by component reference; -1 if not found
property Items[Index: Integer]: TDKLang_CompEntry read GetItems; default; | Items by index
procedure LoadFromDFMResource(Stream: TStream); | Stream loading and storing
procedure Notify(Ptr: Pointer; Action: TListNotification); override; |
property Owner: TDKLang_CompEntry read FOwner; | Owner component entry
procedure SaveToDFMResource(Stream: TStream); |


DKLang / TDKLang_CompEntry

DKLang API / DKLang / TDKLang_CompEntry class

procedure ApplyTranslation(Translation: TDKLang_CompTranslation ; cCodePage: Cardinal); | Recursively replaces the property values with ones found in Translation; if Translation=nil, applies the default property values
procedure BindComponents(CurComponent: TComponent); | Recursively establishes links to components by filling FComponent field with the component reference found by its Name. Also removes components whose names no longer associated with actually instantiated components. Required to be called after loading from the stream
property Component: TComponent read FComponent; | Reference to the component (nil while loading from the stream)
property ComponentNamePath[bIncludeRoot: Boolean]: String read GetComponentNamePath; | Returns component name path in the form 'owner1.owner2.name'. If bIncludeRoot=False, excludes the top-level owner name
function GetComponentNamePath(bIncludeRoot: Boolean): String; |
function GetMaxPropEntryID: Integer; | Returns max property entry ID across all owned components; 0 if list is empty
function GetName: String; |
procedure InternalUpdateEntries(var iFreePropEntryID: Integer; bModifyList, bIgnoreEmptyProps, bIgnoreNonAlphaProps, bIgnoreFontProps: Boolean; IgnoreMasks, StoreMasks: TDKLang_MaskList ); | Internal recursive update routine
procedure InvalidateProps; | Recursively calls PropEntries.Invalidate for each component
procedure LoadFromDFMResource(Stream: TStream); | Stream loading/storing
property Name: String read GetName; | Component name in the IDE
property Owner: TDKLang_CompEntry read FOwner; | Owner entry, can be nil
procedure RemoveComponent(AComponent: TComponent; bRecursive: Boolean); | Removes the given component by reference, if any; if bRecursive=True, acts recursively
procedure SaveToDFMResource(Stream: TStream); |
procedure StoreLangSource(Strings: TWideStrings); | Recursively appends property data as a language source format into Strings
procedure UpdateEntries(bModifyList, bIgnoreEmptyProps, bIgnoreNonAlphaProps, bIgnoreFontProps: Boolean; IgnoreMasks, StoreMasks: TDKLang_MaskList ); | If bModifyList=True, recursively updates (or creates) component hierarchy and component property values, creating and deleting entries as appropriate. If bModifyList=False, only refreshes the [current=default] property values


DKLang / TDKLang_CompTranslation

DKLang API / DKLang / TDKLang_CompTranslation class

List of property value translations for the whole component hierarchy (usually for a single form); a plain list indexed (and sorted) by ID

function Add(iID: Integer; const wsValue: WideString; TranStates: TDKLang_TranslationStates): Integer; | Adds an entry into the list and returns the index of the newly added entry
property ComponentName: String read FComponentName; | Root component's name for which the translations in the list are (form, frame, datamodule etc)
function FindID(iID: Integer; out iIndex: Integer): Boolean; | Tries to find the entry by property ID; returns True, if succeeded, and its index in iIndex; otherwise returns False and its adviced insertion-point index in iIndex
function FindPropByID(iID: Integer): PDKLang_PropValueTranslation ; | Returns the property entry for given ID, or nil if not found
function GetItems(Index: Integer): PDKLang_PropValueTranslation ; |
function IndexOfID(iID: Integer): Integer; | Returns index of entry by its ID; -1 if not found
property Items[Index: Integer]: PDKLang_PropValueTranslation read GetItems; default; | Translations by index
procedure Notify(Ptr: Pointer; Action: TListNotification); override; |


DKLang / TDKLang_CompTranslations

DKLang API / DKLang / TDKLang_CompTranslations class

List of component translations

function Add(Item: TDKLang_CompTranslation ): Integer; | Adds an item to the list and returns the index of the newly added entry
procedure Clear; override; |
property Constants: TDKLang_Constants read FConstants; | Constant entries
function FindComponentName(const sComponentName: String): TDKLang_CompTranslation ; | Returns component translation entry by component name; nil if not found
function GetItems(Index: Integer): TDKLang_CompTranslation ; |
function GetLangIDCallback: LANGID; | Callback function for obtaining current language ID
function IndexOfComponentName(const sComponentName: String): Integer; | Returns index of entry by component name; -1 if not found
property IsStreamUnicode: Boolean read FIsStreamUnicode; | True if last loading from text file/stream detected that it used Unicode encoding; False if it was ANSI
property Items[Index: Integer]: TDKLang_CompTranslation read GetItems; default; | Component translations by index
procedure Notify(Ptr: Pointer; Action: TListNotification); override; |
property Params: TWideStrings read FParams; | Simple parameters stored in a translation file BEFORE the first section (ie. sectionless)
procedure Text_LoadFromFile(const wsFileName: WideString; bParamsOnly: Boolean = False); | File loading in plaintext (ini-file-like) format
procedure Text_LoadFromResource(Instance: HINST; iResID: Integer; bParamsOnly: Boolean = False); overload; |
procedure Text_LoadFromStream(Stream: TStream; bParamsOnly: Boolean = False); | Stream loading and storing in plaintext (ini-file-like) format. bParamsOnly tells the object to load only the sectionless parameters and not to load components nor constants. This may be used to evaluate the translation parameters only (eg. its language)
procedure Text_SaveToFile(const wsFileName: WideString; bUnicode, bSkipUntranslated: Boolean); | File storing in plaintext (ini-file-like) format: bUnicode - if False, stores the data in ANSI encoding; if True, stores them in Unicode bSkipUntranslated - if True, untranslated values are eliminated from the file
procedure Text_SaveToStream(Stream: TStream; bUnicode, bSkipUntranslated: Boolean); |


DKLang / TDKLang_Constant

DKLang API / DKLang / TDKLang_Constant record

sName: String | Constant name, written obeying standard rules for identifier naming
TranStates: TDKLang_TranslationStates | Translation states
wsDefValue: WideString | Default constant value (in the default language; initially the same as wsValue)
wsValue: WideString | Constant value


DKLang / TDKLang_Constants

DKLang API / DKLang / TDKLang_Constants class

function _AddRef: Integer; stdcall; |
function _Release: Integer; stdcall; |
function Add(const sName: String; const wsValue: WideString; TranStates: TDKLang_TranslationStates): Integer; | Add an entry into the list; returns the index of the newly inserted entry
property AsRawString: String read GetAsRawString write SetAsRawString; | Binary list representation as raw data
property AutoSaveLangSource: Boolean read FAutoSaveLangSource write FAutoSaveLangSource; | If True (default), the list will be automatically saved into the Project's language resource file (*.dklang)
function FindConstName(const sName: String): PDKLang_Constant ; | Finds the constant by name; returns nil if not found
function FindName(const sName: String; out iIndex: Integer): Boolean; | Tries to find the entry by name; returns True, if succeeded, and its index in iIndex; otherwise returns False and its adviced insertion-point index in iIndex
function GetAsRawString: String; |
function GetItems(Index: Integer): PDKLang_Constant ; |
function GetItemsByName(const sName: String): PDKLang_Constant ; |
function GetValues(const sName: String): WideString; |
function IDKLang_LanguageSourceObject .GetSectionName = LSO_GetSectionName; |
function IndexOfName(const sName: String): Integer; | Returns index of entry by name; -1 if not found
property Items[Index: Integer]: PDKLang_Constant read GetItems; default; | Constants by index
property ItemsByName[const sName: String]: PDKLang_Constant read GetItemsByName; | Constants by name. If no constant of that name exists, an Exception is raised
function LoadFromResource(Instance: HINST; const wsResName: WideString): Boolean; | Loads the constants from binary resource with the specified name. Returns True if resource existed, False otherwise
procedure LoadFromStream(Stream: TStream); | Stream loading/storing
function LSO_CanStore: Boolean; |
function LSO_GetSectionName: WideString; |
procedure LSO_StoreLangSource(Strings: TWideStrings; StateFilter: TDKLang_TranslationStates); |
procedure Notify(Ptr: Pointer; Action: TListNotification); override; |
function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall; | IInterface
procedure SaveToStream(Stream: TStream); |
procedure SetAsRawString(const Value: String); |
procedure SetValues(const sName: String; const wsValue: WideString); |
procedure TranslateFrom(Constants: TDKLang_Constants ); | Updates the values for existing names from Constants. If Constants=nil, reverts the values to their defaults (wsDefValue)
property Values[const sName: String]: WideString read GetValues write SetValues; | Constant values, by name. If no constant of that name exists, an Exception is raised


DKLang / TDKLang_LangResource

DKLang API / DKLang / TDKLang_LangResource record

Instance: HINST | Instance containing the resource (Kind=[dklrkResName, dklrkResID])
iResID: Integer | Resource ID (Kind=dklrkResID)
Kind: TDKLang_LangResourceKind | Entry kind
wLangID: LANGID | Language contained in the resource
wsName: WideString | File (Kind=dklrkFile) or resource (Kind=dklrkResName) name


DKLang / TDKLang_LangResources

DKLang API / DKLang / TDKLang_LangResources class

function Add(Kind: TDKLang_LangResourceKind; Instance: HINST; const wsName: WideString; iResID: Integer; wLangID: LANGID): Integer; |
function FindLangID(wLangID: LANGID): PDKLang_LangResource ; | Returns the entry having the specified LangID; nil if no such entry
function GetItems(Index: Integer): PDKLang_LangResource ; |
function IndexOfLangID(wLangID: LANGID): Integer; | Returns the index of entry having the specified LangID; -1 if no such entry
property Items[Index: Integer]: PDKLang_LangResource read GetItems; default; | Items by index
procedure Notify(Ptr: Pointer; Action: TListNotification); override; |


DKLang / TDKLang_MaskList

DKLang API / DKLang / TDKLang_MaskList class

A list of masks capable of testing an arbitrary string for matching. A string is considered matching when it matches any mask from the list

function GetItems(Index: Integer): TMask; |
property Items[Index: Integer]: TMask read GetItems; default; | Masks by index
function Matches(const s: String): Boolean; | Returns True if s matches any mask from the list


DKLang / TDKLang_PropEntries

DKLang API / DKLang / TDKLang_PropEntries class

List of property entries (sorted by property name, case-insensitively)

function Add(iID: Integer; const sPropName: String; const wsDefLangValue: WideString): Boolean; | Add an entry into the list (returns True) or replaces the property value with sDefLangValue if property with this name already exists (and returns False). Also sets bValidated to True
procedure DeleteInvalidEntries; | Deletes all invalid entries
function FindPropByName(const sPropName: String): PDKLang_PropEntry ; | Returns entry by property name; nil if not found
function FindPropName(const sPropName: String; out iIndex: Integer): Boolean; | Tries to find the entry by property name; returns True, if succeeded, and its index in iIndex; otherwise returns False and its adviced insertion-point index in iIndex
function GetItems(Index: Integer): PDKLang_PropEntry ; |
function GetMaxID: Integer; | Returns max property entry ID over the list; 0 if list is empty
function IndexOfID(iID: Integer): Integer; | Returns index of entry by its ID; -1 if not found
function IndexOfPropName(const sPropName: String): Integer; | Returns index of entry by property name; -1 if not found
procedure Invalidate; | Resets bValidated flag for each entry
property Items[Index: Integer]: PDKLang_PropEntry read GetItems; default; | Entries by index
procedure LoadFromDFMResource(Stream: TStream); | Stream loading and storing
procedure Notify(Ptr: Pointer; Action: TListNotification); override; |
procedure SaveToDFMResource(Stream: TStream); |


DKLang / TDKLang_PropEntry

DKLang API / DKLang / TDKLang_PropEntry record

bValidated: Boolean | Validation flag, used internally in TDKLang_CompEntry.UpdateEntries
iID: Integer | An entry ID, form-wide unique and permanent
sPropName: String | Component's property name to which the entry is applied
wsDefLangValue: WideString | The property's value for the default language, represented as a widestring


DKLang / TDKLang_PropValueTranslation

DKLang API / DKLang / TDKLang_PropValueTranslation record

iID: Integer | An entry ID, form-wide unique and permanent
TranStates: TDKLang_TranslationStates | Translation states
wsValue: WideString | The property value translation


DKLang / TDKLanguageController

DKLang API / DKLang / TDKLanguageController class

property ActualSectionName: WideString read GetActualSectionName; | Name of a section that is actually used to store and read language data
procedure DefineProperties(Filer: TFiler); override; |
procedure DoLanguageChanged; | Fires the OnLanguageChanged event
procedure DoLanguageChanging; | Fires the OnLanguageChanging event
function GetActualSectionName: WideString; |
function IDKLang_LanguageSourceObject .GetSectionName = GetActualSectionName; |
property IgnoreList: TStrings read FIgnoreList write SetIgnoreList; | List of ignored properties
procedure LangData_Load(Stream: TStream); | Methods for LangData custom property support
procedure LangData_Store(Stream: TStream); |
procedure Loaded; override; |
function LSO_CanStore: Boolean; |
procedure LSO_StoreLangSource(Strings: TWideStrings; StateFilter: TDKLang_TranslationStates); |
procedure Notification(AComponent: TComponent; Operation: TOperation); override; |
property OnLanguageChanged: TNotifyEvent read FOnLanguageChanged write FOnLanguageChanged; | Fires when language is changed through the LangManager
property OnLanguageChanging: TNotifyEvent read FOnLanguageChanging write FOnLanguageChanging; | Fires when language is changed through the LangManager
property Options: TDKLanguageControllerOptions read FOptions write FOptions default DKLang_DefaultControllerOptions; | Language controller options
property RootCompEntry: TDKLang_CompEntry read FRootCompEntry; | The root entry, corresponding to the instance's owner
property SectionName: WideString read FSectionName write FSectionName; | Name of a section corresponding to the form or frame served by the controller. If empty (default), Owner's name is used as section name
procedure SetIgnoreList(Value: TStrings); |
procedure SetStoreList(Value: TStrings); |
property StoreList: TStrings read FStoreList write SetStoreList; | List of forcibly stored properties
procedure UpdateComponents(bModifyList: Boolean); | Forces component entries to update their entries. If bModifyList=False, only default property values are initialized, no entry additions/removes are allowed


DKLang / TDKLanguageManager

DKLang API / DKLang / TDKLanguageManager class

Global thread-safe language manager class

procedure AddLangController(Controller: TDKLanguageController ); | Internal language controller registration procedures (allowed at runtime only)
procedure ApplyTran(Translations: TDKLang_CompTranslations ); | Applies the specified translation to controllers and constants. Translations=nil means the default language to be applied
procedure ApplyTranToController(Translations: TDKLang_CompTranslations ; Controller: TDKLanguageController ); | Applies the specified translation to a single controller. Not a thread-safe method
property CodePage: Cardinal read FCodePage; | Code page corresponding to the current value of LanguageID
property ConstantValue[const sName: String]: WideString read GetConstantValue; | Constant values by name, Unicode version
property ConstantValueA[const sName: String]: String read GetConstantValueA; | Constant values by name, ANSI version
property ConstantValueW[const sName: String]: WideString read GetConstantValue; | Constant values by name, Unicode version; the same as ConstantValue[]
property DefaultLanguageID: LANGID read GetDefaultLanguageID write SetDefaultLanguageID; | Default language ID. The default value is US English ($409)
function GetConstantValue(const sName: String): WideString; |
function GetConstantValueA(const sName: String): String; |
function GetDefaultLanguageID: LANGID; |
function GetLanguageCount: Integer; |
function GetLanguageID: LANGID; |
function GetLanguageIDs(Index: Integer): LANGID; |
function GetLanguageIndex: Integer; |
function GetLanguageNames(Index: Integer): WideString; |
function GetLanguageResources(Index: Integer): PDKLang_LangResource ; |
function GetTranslationsForLang(wLangID: LANGID): TDKLang_CompTranslations ; | Creates and returns the translations object, or nil if wLangID=DefaultLangID or creation failed. Not a thread-safe method
function IndexOfLanguageID(wLangID: LANGID): Integer; | Returns the index of specified LangID, or -1 if not found
property LanguageCount: Integer read GetLanguageCount; | Number of languages (language resources) registered, including the default language
property LanguageID: LANGID read GetLanguageID write SetLanguageID; | Current language ID. Initially equals to DefaultLanguageID. When being changed, affects all the registered language controllers as well as constants
property LanguageIDs[Index: Integer]: LANGID read GetLanguageIDs; | LangIDs of languages (language resources) registered, index ranged 0 to LanguageCount-1
property LanguageIndex: Integer read GetLanguageIndex write SetLanguageIndex; | Current language index
property LanguageNames[Index: Integer]: WideString read GetLanguageNames; | Names of languages (language resources) registered, index ranged 0 to LanguageCount-1, Unicode version only
property LanguageResources[Index: Integer]: PDKLang_LangResource read GetLanguageResources; | Language resources registered, index ranged 0 to LanguageCount-1. Always nil for Index=0, ie. for default language
function RegisterLangFile(const wsFileName: WideString): Boolean; | Registers a translation file for specified language. Returns True if the file was a valid translation file with language specified. The file replaces any language resource for that language registered before. You can never replace the DefaultLanguage though
procedure RegisterLangResource(Instance: HINST; iResID: Integer; wLangID: LANGID); overload; |
procedure RemoveLangController(Controller: TDKLanguageController ); |
function ScanForLangFiles(const wsDir, wsMask: WideString; bRecursive: Boolean): Integer; | Scans the specified directory for language files using given file mask. If bRecursive=True, also searches in the subdirectories of sDir. Returns the number of files successfully registered. Examples that scan the application directory for files with '.lng' extension: ScanForLangFiles(ExtractFileDir(ParamStr(0)), '*.lng', False); // ANSI version, not always correct ScanForLangFiles(WideExtractFileDir(WideParamStr(0)), '*.lng', False); // Unicode version, requires Tnt // Unicode Controls
procedure SetDefaultLanguageID(Value: LANGID); |
procedure SetLanguageID(Value: LANGID); |
procedure SetLanguageIndex(Value: Integer); |
procedure TranslateController(Controller: TDKLanguageController ); | Called by controllers when they are initialized and ready. Applies the currently selected language to the controller
procedure UnregisterLangResource(wLangID: LANGID); | Removes language with the specified LangID from the registered language resources list. You cannot remove the DefaultLanguage
procedure UpdateCodePage; | Updates CodePage in order to match current LanguageID. Not a thread-safe method


DKLangReg

DKLang API / DKLangReg unit

Component, expert and component editor registration routines
Size: 2379


Type Index

DKLang API / Type Index

List of all DKLang API types in alphabetical order

Type | Object | Unit | Comments
class | EDKLangError | DKLang | Error
interface | IDKLang_LanguageSourceObject | DKLang | An interface to an object capable of storing its data as a language source strings
pointer | PDKLang_Constant | DKLang | A constant
pointer | PDKLang_LangResource | DKLang |
pointer | PDKLang_PropEntry | DKLang | A single component property entry
pointer | PDKLang_PropValueTranslation | DKLang | A single component property value translation, referred to by ID
pointer | PResResourceEntryHeader | DKL_ResFile | Resource entry header
pointer | PResResourceEntryProps | DKL_ResFile | Resource entry properties
class | TdDKL_ConstEditor | DKL_ConstEditor |
class | TDKLang_CompEntries | DKLang | List of component entries
class | TDKLang_CompEntry | DKLang |
class | TDKLang_CompTranslation | DKLang | List of property value translations for the whole component hierarchy (usually for a single form); a plain list indexed (and sorted) by ID
class | TDKLang_CompTranslations | DKLang | List of component translations
record | TDKLang_Constant | DKLang |
class | TDKLang_Constants | DKLang |
class | TDKLang_Expert | DKL_Expt | TDKLang_Expert
class | TDKLang_FormNotifier | DKL_Expt | TDKLang_FormNotifier
record | TDKLang_LangResource | DKLang |
class | TDKLang_LangResources | DKLang |
class | TDKLang_MaskList | DKLang | A list of masks capable of testing an arbitrary string for matching. A string is considered matching when it matches any mask from the list
class | TDKLang_OTAIDENotifier | DKL_Expt | TDKLang_OTAIDENotifier
class | TDKLang_PropEntries | DKLang | List of property entries (sorted by property name, case-insensitively)
record | TDKLang_PropEntry | DKLang |
record | TDKLang_PropValueTranslation | DKLang |
class | TDKLang_ResEntry | DKL_ResFile | Single resource entry
class | TDKLang_ResFile | DKL_ResFile |
class | TDKLangControllerEditor | DKL_Expt | TDKLanguageController component editor
class | TDKLanguageController | DKLang |
class | TDKLanguageManager | DKLang | Global thread-safe language manager class
record | TResResourceEntryHeader | DKL_ResFile |
record | TResResourceEntryProps | DKL_ResFile |