Delphi / C++Builder
Delphi and C++Builder localization for VCL applications.
Translate the forms and resource strings of the EXE, DLL, and BPL files you ship, with the DFM preview, check them, and write a localized EXE for each language or resource modules such as MyApp.DEU next to the unchanged EXE. No Delphi project, no rebuild.
- Input
- The
.exe,.dll, and.bplfiles you ship - Output
de\MyApp.exe, orMyApp.DEUnext to the unchanged EXE- Runtime
- Delphi loads
MyApp.DEUby itself - Preview
- Forms in the DFM preview
On this page
Tutorial
Localize a Delphi or C++Builder application, step by step.
Six steps from your EXE, DLL, and BPL files to a localized release.
Lingobit reads the forms of your build and writes them back translated.
Delphi and C++Builder compile forms and resource strings into your EXE, DLL, and BPL files. Lingobit opens those files, shows each form and string table in one tree, and writes the same files with translated resources. Your Pascal and C++ code is not touched, and nothing is rebuilt.
Lingobit does
- Translates form captions, labels, hints, list items, and titles, resource strings, and version information.
- Shows forms in the DFM preview, where you move and resize controls for longer text.
- Checks overlapping controls, accelerators, placeholders, and more.
- Writes a localized file for each language, or resource modules next to the EXE.
Your project keeps
- The Pascal or C++ code and the build in RAD Studio.
- Keeping messages in
resourcestringsections, not in code. - The installer and the files it ships.
- The final test in the running application.
Lingobit also opens .dfm files on their own, for a form that is not compiled yet.
Output options: choose by how you ship.
The default is a localized copy of each file in a language folder. Resource modules keep one EXE for every language, and Delphi picks the module for the Windows language by itself.
Localized EXE, DLL, or BPL files
Resource modules
Reference
Delphi loads the resource module by itself.
At startup, the Delphi runtime looks next to MyApp.exe for a module named after the Windows language: MyApp.DEU for German (Germany), then MyApp.DE. Without one, the application uses the resources in its own EXE.
- A localized EXE needs no loading code: the installer puts
de\MyApp.exein place, or a shortcut starts it. - A language without a country gets a two-letter module: neutral German gives
MyApp.DE, which Delphi loads too.
Choose the language in your app.
Delphi follows the Windows language. To let users pick another one, save their choice where the runtime reads it at startup: a value in its Locales key under HKEY_CURRENT_USER, named after the full path of MyApp.exe. The key name depends on your Delphi version; Software\Borland\Locales is the one shown here.
- List the languages you ship from the modules next to
MyApp.exe. - Save the user's choice as the module extension, such as
DEU. - Restart the application: the runtime reads the choice before your code runs.
uses Registry;
procedure SaveLanguage(const Ext: string); // 'DEU', 'FRA', ...
begin
with TRegistry.Create do
try
OpenKey('Software\Borland\Locales', True);
WriteString(ParamStr(0), Ext); // used from the next start
finally
Free;
end;
end;
Do and don't.
Do
- Localize the Release build you ship, with its DLL and BPL files.
- Keep messages in
resourcestringsections; move hard-coded strings with Lingobit Extractor. - Keep form and component names stable between releases.
- Leave room in forms, and resize controls in the DFM preview where German runs long.
- Name each resource module after its EXE and keep it in the same folder.
Don't
- Build messages from translated pieces in code.
- Edit localized forms by hand: Create Localized Files writes them from your next build.
- Send Pascal, C++, or DFM files to translators.
Typical localizability problems in Delphi and C++Builder applications.
Problems in the code that translation cannot fix, how each shows up in the localized build, and how to find it before translators start. The general checklist is in Software internationalization; the test build in Pseudo-localization.
| Problem | How it shows | Find and fix |
|---|---|---|
| Messages are string constants in code | ShowMessage('Saved') stays in English | Declare them as resourcestring; Lingobit Extractor finds hard-coded Delphi strings |
| Sentences are built from pieces | Word order is wrong in other languages | Use Format with indexed placeholders such as %0:s; Validation reports placeholders that do not match the source |
| Forms only fit English | Captions are cut off or controls overlap | Use AutoSize and anchors; Validation reports overlapping controls, and you resize them in the DFM preview |
| Accelerators collide | Two menu items share a letter | Validation reports duplicate and missing accelerators |
| The application is not Unicode | Text outside the code page turns into question marks | Create Localized Files lists the characters the code page cannot hold; Unicode Delphi versions avoid the problem |
Troubleshooting.
| Symptom | Likely cause | What to do |
|---|---|---|
| The application stays in English with resource modules | The module is not next to MyApp.exe, its name does not match the EXE, or its language is not the Windows language | Check the folder and the name, or save the language in the Locales key |
| Text is cut off in a form | The translation is longer than the control | Run Validation: it reports overlapping controls. Resize the control in the DFM preview |
| Two menu items share a shortcut | The translation repeats an accelerator letter | Validation reports duplicate and missing accelerators |
| Create Localized Files reports characters that cannot be encoded | VCL Unicode Support is Off, and the translation has characters outside the language's code page | For a Unicode application (Delphi 2009 and later), set VCL Unicode Support to On; otherwise remove the characters |
| Japanese text shows as question marks | The application is not Unicode, and Windows shows its text in the system code page | Test with Japanese as the language for non-Unicode programs, or move the application to a Unicode Delphi version |
More about Delphi and C++Builder localization.
DFM files as input
Lingobit also takes .dfm, .nfm, and .rtm form files. When you start from .dfm files, Create Localized Files writes a translated copy for each language, such as de\MainForm.dfm, and your team builds the localized forms in its own Delphi build or packaging process.
Use DFM files when localization must happen before compilation, when the team already has a DFM-based workflow, or when a legacy project cannot yet move to binary localization. Prefer binary localization when you want to localize the application exactly as it ships, without project files for translators or manual IDE steps for each language.
Delphi source code: preparation only
When user-facing strings are still hardcoded in Pascal code, developers move them into resourcestring declarations before localization starts; Lingobit Extractor finds them. Pascal source files are not the translator's handoff, and translation does not change event handlers, component logic, or application behavior.
unit AppResources;
interface
resourcestring
SWelcomeMessage = 'Welcome';
SSaveChanges = 'Save changes before closing?';
implementation
end.
Clear boundaries
- Translators do not work in the Delphi IDE, and form preview is not an IDE replacement: forms are not redesigned there.
- Lingobit does not redesign the application's internationalization or move hardcoded strings into resources for you.
- The application decides between localized binaries and resource modules, packages them, and offers any language choice other than the Windows language.
Delphi and C++Builder localization FAQ
Do I need the Delphi project or the source code?
No. Lingobit reads the forms and resource strings from the EXE, DLL, and BPL files you ship and writes them back translated; RAD Studio is not needed for the translation. It also opens .dfm files on their own, for forms that are not compiled yet.
How do I translate the VCL's own messages, such as the MessageDlg buttons?
Strings of Vcl.Consts and the other RTL and VCL units are resource strings that are compiled into your EXE, or into the runtime packages you ship. Lingobit lists them with your own strings; translate them like the rest, or add the BPL files when the application uses runtime packages.
Why do resource strings stay in the old language after I load another resource module?
Since Delphi 10.4 the RTL caches resource strings once they are loaded, so switching the module while the application runs leaves those strings in the previous language. Choose the language before the application starts, and restart after the user picks another one, as in Choose the language in your app.
gettext, a component suite, or resource modules: which approach?
gettext keeps the translations in .po files and translates forms at runtime from code. Component suites keep translations in components inside the application. Resource modules are Delphi's own mechanism: the runtime loads MyApp.DEU without code changes, and each language can have its own sizes and positions. Lingobit works with the compiled files and writes resource modules or a localized EXE for each language.
Related paths
- Preparation — Lingobit Extractor and pseudo-translation before translators start.
- Resource-only DLLs — Resource modules such as MyApp.DEU, and their Win32 and MFC counterparts.
- Localization QA — Validation, layout checks, and Crash Finder.
- Win32 / MFC — The same binary localization for native C++ applications.
- Migration — Bring translations from your existing localized EXE files.