Win32 / MFC
Win32 and MFC localization for native Windows applications.
Translate the dialogs, menus, and string tables of the EXE and DLL files you ship, in the visual editor, check them, and write a localized EXE for each language or resource-only DLLs next to the unchanged EXE. No source code, no rebuild.
- Input
- The
.exeand.dllfiles you ship - Output
de\MyApp.exe, orMyAppDEU.dllnext to the unchanged EXE- Runtime
- MFC loads
MyAppDEU.dllby itself - Preview
- Dialogs and menus in the visual editor
On this page
Tutorial
Localize a Win32 or MFC application, step by step.
Six steps from your EXE and DLL files to a localized release.
Lingobit reads the resources of your build and writes them back translated.
Dialogs, menus, and string tables are compiled into your EXE and DLL files as Windows resources. Lingobit opens those files, shows each resource in one tree, and writes the same files with translated resources. Your code is not touched, and nothing is rebuilt.
Lingobit does
- Translates dialogs, menus, string tables, accelerators, version information, message tables, MFC combo box lists, toolbars, and ribbons (Professional and higher: category, panel, and button names; tooltips and descriptions with an XPath rule).
- Shows dialogs and menus in the visual editor, where you resize controls for longer text.
- Checks truncated text, accelerators, placeholders, and more.
- Writes a localized EXE or DLL for each language, or resource-only DLLs.
Your project keeps
- The C++ code and the build in Visual Studio.
- Keeping UI text in resources, not in code.
- The installer and the language folders it ships.
- The final test in the running application.
Output options: choose by how you ship.
The default is a localized copy of each file in a language folder. Resource-only DLLs keep one EXE for every language. Several languages in one file are possible, but rarely the right choice.
Localized EXE or DLL files
Resource-only DLLs
Multi-language binaries
Reference
MFC loads the language DLL by itself.
At startup, CWinApp::InitInstance goes through the user's UI languages and loads MyAppDEU.dll from the folder of MyApp.exe for German, MyAppFRA.dll for French. Without a matching DLL, 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. - Plain Win32 code loads the DLL itself and takes its strings and dialogs from it.
// Plain Win32: load the resources, keep the code in MyApp.exe
HMODULE res = LoadLibraryExW(L"MyAppDEU.dll", nullptr,
LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
LoadStringW(res ? res : hInstance, IDS_SAVED, text, _countof(text));
Choose the language in your app.
MFC follows the Windows language. To let users pick another one, set it before MFC loads the DLL:
- List the languages you ship from the DLLs next to
MyApp.exe. - Read the saved choice or a command-line switch; otherwise leave the Windows language.
- Set it before
CWinApp::InitInstancewithSetThreadPreferredUILanguages. - Switch by restarting, or use Multilingual Library for a language menu.
BOOL CMyApp::InitInstance()
{
ULONG count = 0;
SetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, L"de-DE\0", &count);
CWinApp::InitInstance(); // loads MyAppDEU.dll
...
}
Do and don't.
Do
- Localize the Release build you ship, and add its DLLs too.
- Keep UI text in resources; move hard-coded strings with Lingobit Extractor.
- Keep resource IDs stable between releases.
- Leave room in dialogs, and resize controls in the visual editor where German runs long.
- Keep resource-only DLLs in the folder of
MyApp.exe, and callCWinApp::InitInstancein yours.
Don't
- Build messages from translated pieces in code.
- Rebuild the localized files by hand: Create Localized Files writes them from your next build.
- Send RC files or C++ code to translators.
- Put several languages into one file unless your distribution needs it.
Typical localizability problems in Win32 and MFC 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 |
|---|---|---|
| Strings are written in C++ code | AfxMessageBox(_T("Saved")) stays in English | Move them into the string table; Lingobit Extractor finds hard-coded C++ strings and writes the resources |
Messages are built with %s in a fixed order | Translators cannot change the word order | Use one string per message; FormatMessage with %1, %2 lets the order change. Validation reports C++ format strings that do not match |
| Dialog controls only fit English | Text is cut off in dialogs | Validation reports truncated text; Automatically resize dialog elements grows the control, or resize it in the visual editor |
| Accelerators collide | Two menu items or controls share a letter | Validation reports duplicate and missing accelerators; Check Mnemonics shows them in a dialog |
| The build is not Unicode | Japanese or Russian text shows as question marks | Build for Unicode; Create Localized Files lists characters the code page of the file cannot hold |
| The dialog font has no glyphs for the language | Boxes instead of characters | Set a dialog font for that language in the visual editor |
| Right-to-left languages | Dialogs read in the wrong direction | Flip mirrors dialogs for Arabic and Hebrew |
Troubleshooting.
| Symptom | Likely cause | What to do |
|---|---|---|
| The application stays in English with resource-only DLLs | The DLL is not next to MyApp.exe, its language is not among the user's UI languages, the application's InitInstance does not call CWinApp::InitInstance, or plain Win32 code does not load it | Check the folder and the name, call the base InitInstance, or load the DLL in your code |
| Text is cut off in a dialog | The translation is longer than the control | Run Validation: it reports truncated text in dialogs. Resize the control in the visual editor |
| Two menu items share a shortcut | The translation repeats an accelerator letter | Validation reports duplicate and missing accelerators |
| The application crashes with one language | A translation breaks a placeholder or a resource the code depends on | Run Validation; if the cause is not obvious, Crash Finder narrows it down to the translation (Enterprise) |
| 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 build the application for Unicode |
The MFC samples.
Localizer installs MFC samples with their projects, one for each way to ship.
- Simple MFC: a localized EXE for each language.
- Resource DLL: one EXE with a resource-only DLL for each language, and a language switch at run time.
- MFC Multilingual: several languages in one application file.
More about Win32 and MFC localization.
Visual dialog editing: what to check
Win32 and MFC localization is not only text replacement. Dialogs must still look correct after translation, with readable labels, stable shortcuts, and enough room for longer languages. In the visual editor, look for:
- cropped or truncated text, and overlapping controls;
- buttons that become too small, and labels that no longer align with their fields;
- incorrect or duplicated accelerator keys;
- dialogs that need different spacing in longer languages.
RC, RES, and C++ source files: preparation only
RC, RES, and C++ source processing is not the main localization workflow for Win32 and MFC applications. It does not replace binary localization, does not give the same visual dialog workflow, and is not a handoff for translators. Use it as a developer-side step before binary localization:
- finding hardcoded C++ UI strings and moving them into native resources;
- reviewing legacy RC files during cleanup;
- preparing an old project for later binary localization.
When a translated .rc is what you need: Translate .rc files.
MFC ribbons: names, tooltips, descriptions
The MFC ribbon is XML: the .mfcribbon-ms file from the Visual Studio ribbon designer, compiled into the EXE as an RT_RIBBON_XML resource. Lingobit reads it in both places with the MFC Ribbon format, in Professional and higher; in Standard the ribbon resource is copied unchanged. By default the category, panel, and button names (NAME, TEXT) are translated. To translate tooltips and descriptions too, extend Select nodes to translate on the Parser page:
//CATEGORY/NAME | //TEXT | //PANEL/NAME | //TOOLTIP | //DESCRIPTION
Key tips (KEYS) are not in the rule; add //KEYS if the languages need their own.
What translators should not receive
- Visual Studio projects, RC files, or C++ source files as the translation input.
- Manual rebuild steps for each language.
- Developer cleanup that belongs before binary localization.
Win32 and MFC localization FAQ
Can I translate only some dialogs and leave the rest in English?
Yes. Lingobit writes the whole resource set into the localized EXE or the resource-only DLL; items that are not translated yet keep the original text. You can translate a few dialogs per release, and the DLL still contains every dialog, menu, and string.
Do I have to redraw every dialog for each language?
No. The dialogs come from your build. In the visual editor you type the translation in place and resize controls only where a language needs more room. Automatically resize dialog elements, on by default, grows a control when its translation does not fit, and a language can have its own dialog font. The changes are stored in the translation, not in your .rc files.
How do I change the language of AfxMessageBox?
The message is your string resource and is translated with the other string tables. The OK, Cancel, Yes, and No buttons are drawn by Windows; they follow the Windows display language, not your DLL.
Resource-only DLLs or a localized EXE for each language?
Resource-only DLLs fit when one EXE serves every language and MFC picks the language at startup. A localized EXE fits when each installer ships one language. Lingobit writes either from the same project; see Resource-only DLLs.
Related paths
- Multilingual Library — A language menu for MFC applications.
- Resource-only DLLs — Names, loading code, and building language DLLs.
- Localization QA — Validation, truncation checks, and Crash Finder.
- Delphi / C++Builder — The same binary localization for VCL applications.
- Migration — Bring translations from your existing localized EXE and DLL files.