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.

Translated with another tool? See how migration works

Your build EXE MyApp.exe Lingobit Localizer Harbor Supply 12 New Order Neue Bestellung Customer: Kunde: Quantity: Menge: Create Cancel Erstellen Abbrechen The dialog as it is in the EXE, translated in the visual editor You ship EXE MyApp.exe DEde\ FRfr\ JAja\ A localized MyApp.exe in each language folder, or resource-only DLLs Your build EXE MyApp.exe Translate in LingobitVisual editor Harbor Supply 12 New Order Neue Bestellung Customer: Kunde: Quantity: Menge: Create Cancel Erstellen Abbrechen You ship EXE MyApp.exe original DEde\ FRfr\ JAja\
Input
The .exe and .dll files you ship
Output
de\MyApp.exe, or MyAppDEU.dll next to the unchanged EXE
Runtime
MFC loads MyAppDEU.dll by 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.

Text in code C++ AfxMessageBox("Saved."); Stays in English in every language Extractor Text in resources C++ AfxMessageBox(IDS_SAVED); RC MyApp.rc IDS_SAVEDSaved. DE Gespeichert. Translated with the dialogs Text in code stays in English C++ AfxMessageBox("Saved."); Extractor Text in resources C++ AfxMessageBox(IDS_SAVED); RC MyApp.rc IDS_SAVEDSaved. DE Gespeichert. Translated with the dialogs
Pseudo Translate German Simulation · +30% Chinese Simulation Harbor Supply 12 Saved at 10:42 Orders ÖrderßÖ ?????? Customer: Cüßtömer:Cü 阿昂俩拉基豪拉恶: Quantity: Qüäntity:Qü 阿昂阿拉拉哈拉哟: Ship today Ship tödäyShi 俩色哈勒 拉基俄阿哟 Create Cancel CreäteC CäncelC 阿恶拉阿拉拉 阿阿拉阿拉瑟 Too long Still in English Not displayed Pseudo Translate German Simulation · +30% Chinese Simulation Harbor Supply 12 Saved at 10:42 Orders ÖrderßÖ ?????? Customer: Cüßtömer:Cü 阿昂俩拉基豪拉恶: Quantity: Qüäntity:Qü 阿昂阿拉拉哈拉哟: Ship today Ship tödäyShi 俩色哈勒 拉基俄阿哟 Create Cancel CreäteC CäncelC 阿恶拉阿拉拉 阿阿拉阿拉瑟 Too long Still in English Not displayed
  1. Text in code C++ AfxMessageBox("Saved."); Stays in English in every language Extractor Text in resources C++ AfxMessageBox(IDS_SAVED); RC MyApp.rc IDS_SAVEDSaved. DE Gespeichert. Translated with the dialogs Text in code stays in English C++ AfxMessageBox("Saved."); Extractor Text in resources C++ AfxMessageBox(IDS_SAVED); RC MyApp.rc IDS_SAVEDSaved. DE Gespeichert. Translated with the dialogs
  2. Pseudo Translate German Simulation · +30% Chinese Simulation Harbor Supply 12 Saved at 10:42 Orders ÖrderßÖ ?????? Customer: Cüßtömer:Cü 阿昂俩拉基豪拉恶: Quantity: Qüäntity:Qü 阿昂阿拉拉哈拉哟: Ship today Ship tödäyShi 俩色哈勒 拉基俄阿哟 Create Cancel CreäteC CäncelC 阿恶拉阿拉拉 阿阿拉阿拉瑟 Too long Still in English Not displayed Pseudo Translate German Simulation · +30% Chinese Simulation Harbor Supply 12 Saved at 10:42 Orders ÖrderßÖ ?????? Customer: Cüßtömer:Cü 阿昂俩拉基豪拉恶: Quantity: Qüäntity:Qü 阿昂阿拉拉哈拉哟: Ship today Ship tödäyShi 俩色哈勒 拉基俄阿哟 Create Cancel CreäteC CäncelC 阿恶拉阿拉拉 阿阿拉阿拉瑟 Too long Still in English Not displayed

Your build EXE MyApp.exe Project DE FR JA EXE MyApp.exe Dialogs New Order Print Invoice Menus String Table Accelerators Version EXE Your build EXE MyApp.exe Project DE FR JA EXE MyApp.exe Dialogs New Order Print Invoice Menus String Table Accelerators Version EXE
  1. Your build EXE MyApp.exe Project DE FR JA EXE MyApp.exe Dialogs New Order Print Invoice Menus String Table Accelerators Version EXE Your build EXE MyApp.exe Project DE FR JA EXE MyApp.exe Dialogs New Order Print Invoice Menus String Table Accelerators Version EXE

Visual editor Dialogs › Print Invoice Print Invoice Printer: Office printer Copies: 2 Include payment details Template: HS-INV-01 Print Cancel Locked Visual editor Dialogs › Print Invoice Print Invoice Printer: Office printer Copies: 2 Include payment details Template: HS-INV-01 Print Cancel Locked
ProjectDEFRJAMyApp.exeDialogsNew OrderMenus PrepareTranslationTaskImportTranslationResults TranslatorDENew OrderNeue BestellungCustomer:Kunde:CreateErstellenSourceGermanNew OrderNeue BestellungCustomer:Kunde:Quantity:Menge:Validation on save Or their CAT toolXLIFF 1.2for the tool the translatoralready uses ProjectDEFRJAMyApp.exeDialogsNew OrderMenus PrepareTranslation Task TranslatorDENew OrderNeue BestellungCustomer:Kunde:CreateErstellenSourceGermanNew OrderNeue BestellungCustomer:Kunde:Quantity:Menge:Validation on save Or their CAT toolXLIFF 1.2for the tool the translatoralready uses ImportResults
Project Auto Translate Using Harbor Supply 12 New Order Neue Bestellung Customer: Kunde: Quantity: Menge: Ship today Noch heute versenden Create Cancel Erstellen Abbrechen DeepL… Google Translate… Azure Translator… Translation Memory… Terminology… Pseudo Translate… Project Auto Translate Using Harbor Supply 12 New Order Neue Bestellung Customer: Kunde: Quantity: Menge: Ship today Noch heute versenden Create Cancel Erstellen Abbrechen DeepL… Google Translate… Azure Translator… Translation Memory… Terminology… Pseudo Translate…
  1. Visual editor Dialogs › Print Invoice Print Invoice Printer: Office printer Copies: 2 Include payment details Template: HS-INV-01 Print Cancel Locked Visual editor Dialogs › Print Invoice Print Invoice Printer: Office printer Copies: 2 Include payment details Template: HS-INV-01 Print Cancel Locked
  2. ProjectDEFRJAMyApp.exeDialogsNew OrderMenus PrepareTranslationTaskImportTranslationResults TranslatorDENew OrderNeue BestellungCustomer:Kunde:CreateErstellenSourceGermanNew OrderNeue BestellungCustomer:Kunde:Quantity:Menge:Validation on save Or their CAT toolXLIFF 1.2for the tool the translatoralready uses ProjectDEFRJAMyApp.exeDialogsNew OrderMenus PrepareTranslation Task TranslatorDENew OrderNeue BestellungCustomer:Kunde:CreateErstellenSourceGermanNew OrderNeue BestellungCustomer:Kunde:Quantity:Menge:Validation on save Or their CAT toolXLIFF 1.2for the tool the translatoralready uses ImportResults
  3. Project Auto Translate Using Harbor Supply 12 New Order Neue Bestellung Customer: Kunde: Quantity: Menge: Ship today Noch heute versenden Create Cancel Erstellen Abbrechen DeepL… Google Translate… Azure Translator… Translation Memory… Terminology… Pseudo Translate… Project Auto Translate Using Harbor Supply 12 New Order Neue Bestellung Customer: Kunde: Quantity: Menge: Ship today Noch heute versenden Create Cancel Erstellen Abbrechen DeepL… Google Translate… Azure Translator… Translation Memory… Terminology… Pseudo Translate…

Preview Neue Bestellung Kunde Kunde: Harbor Supply Menge: 12 Noch heute versenden Noch heute versenden Erstellen Stornieren Abbrechen Output Validation · German Fix ! Missing colon Kunde Fixed ! Translation memory mismatch "Stornieren", must be "Abbrechen" ! Text truncation in dialog Noch heute versenden Fixed Fixed Preview Neue Bestellung Kunde Kunde: Harbor Supply Menge: 12 Noch heute versenden Noch heute versenden Erstellen Stornieren Abbrechen Output Validation · German Fix ! Missing colon Kunde Fixed ! Translation memory mismatch "Stornieren", must be "Abbrechen" Fixed ! Text truncation in dialog Noch heute versenden Fixed
MyApp · German ! An unexpected error occurred. OK Which translation causes it? German version: error Which translation causes it? All translations Run 1Error Run 2Works Run 3Error Run 4Works … Found Source Order {0} was saved. Translation Bestellung {1} wurde gespeichert. {1} instead of {0} makes the application fail. MyApp · German ! An unexpected error occurred. OK Which translation causes it? German version: error Which translation? All translations Run 1Error Run 2Works Run 3Error Run 4Works … Found Source Order {0} was saved. Translation Bestellung {1} wurde gespeichert. {1} instead of {0} makes the application fail.
  1. Preview Neue Bestellung Kunde Kunde: Harbor Supply Menge: 12 Noch heute versenden Noch heute versenden Erstellen Stornieren Abbrechen Output Validation · German Fix ! Missing colon Kunde Fixed ! Translation memory mismatch "Stornieren", must be "Abbrechen" ! Text truncation in dialog Noch heute versenden Fixed Fixed Preview Neue Bestellung Kunde Kunde: Harbor Supply Menge: 12 Noch heute versenden Noch heute versenden Erstellen Stornieren Abbrechen Output Validation · German Fix ! Missing colon Kunde Fixed ! Translation memory mismatch "Stornieren", must be "Abbrechen" Fixed ! Text truncation in dialog Noch heute versenden Fixed
  2. MyApp · German ! An unexpected error occurred. OK Which translation causes it? German version: error Which translation causes it? All translations Run 1Error Run 2Works Run 3Error Run 4Works … Found Source Order {0} was saved. Translation Bestellung {1} wurde gespeichert. {1} instead of {0} makes the application fail. MyApp · German ! An unexpected error occurred. OK Which translation causes it? German version: error Which translation? All translations Run 1Error Run 2Works Run 3Error Run 4Works … Found Source Order {0} was saved. Translation Bestellung {1} wurde gespeichert. {1} instead of {0} makes the application fail.

Project MyApp.exe New Order Print Invoice String Table DE FR JA Create Localized Files Run Localized Application Release folder EXE MyApp.exe DLL Core.dll unchanged DEde\MyApp.exe FRfr\MyApp.exe JAja\MyApp.exe Neue Bestellung Kunde: Harbor Supply Erstellen Abbrechen Project MyApp.exe New Order Print Invoice Create Localized Files EXE MyApp.exe · Core.dll unchanged DEde\ FRfr\ JAja\ Run Localized Application Neue Bestellung Kunde: Harbor Supply Erstellen Abbrechen
New build EXE MyApp.exe DLL Core.dll no source code + Project Dialogs Menus String Table DE FR JA = 新規注文 Nouvelle commande Neue Bestellung Kunde: Menge: Erstellen Run and test right away New build · no source code EXE DLL MyApp.exe Core.dll + Project Complete DE FR JA = Neue Bestellung Kunde: Erstellen Run and test right away
  1. Project MyApp.exe New Order Print Invoice String Table DE FR JA Create Localized Files Run Localized Application Release folder EXE MyApp.exe DLL Core.dll unchanged DEde\MyApp.exe FRfr\MyApp.exe JAja\MyApp.exe Neue Bestellung Kunde: Harbor Supply Erstellen Abbrechen Project MyApp.exe New Order Print Invoice Create Localized Files EXE MyApp.exe · Core.dll unchanged DEde\ FRfr\ JAja\ Run Localized Application Neue Bestellung Kunde: Harbor Supply Erstellen Abbrechen
  2. New build EXE MyApp.exe DLL Core.dll no source code + Project Dialogs Menus String Table DE FR JA = 新規注文 Nouvelle commande Neue Bestellung Kunde: Menge: Erstellen Run and test right away New build · no source code EXE DLL MyApp.exe Core.dll + Project Complete DE FR JA = Neue Bestellung Kunde: Erstellen Run and test right away

MyApp.exe 1.0 1.1 New Order Customer: Client: Harbor Supply Quantity: 12 Ship today Gift wrap Create Cancel Project Scan for Changes Neue Bestellung Kunde: Updated Harbor Supply Menge: 12 Noch heute versenden Removed Gift wrap New Erstellen Abbrechen MyApp.exe 1.0 1.1 New Order Customer: Client: Harbor Supply Quantity: 12 Ship today Gift wrap Create Cancel Project Scan for Changes Neue Bestellung Kunde: Updated Harbor Supply Menge: 12 Noch heute versenden Removed Gift wrap New Erstellen Abbrechen
Translated earlier MyApp.exe de\ DE MyApp.exe fr\ FR MyApp.exe Project Not Translated Imported DE FR MyApp.exe Dialogs Menus String Table Import from Localized Files Translated with another tool or long ago? Add your build: Lingobit finds the localized files and offers to import them. Import Translations from Localized Files Germande\MyApp.exe Frenchfr\MyApp.exe OK Cancel OK Translated earlier MyApp.exe de\ DE MyApp.exe fr\ FR MyApp.exe Project Not Translated Imported DE FR MyApp.exe Dialogs Menus String Table Import from Localized Files Translated with another tool or long ago? Add your build: Lingobit offers the import. Import Translations from Localized Files Germande\MyApp.exe Frenchfr\MyApp.exe OK Cancel OK
  1. MyApp.exe 1.0 1.1 New Order Customer: Client: Harbor Supply Quantity: 12 Ship today Gift wrap Create Cancel Project Scan for Changes Neue Bestellung Kunde: Updated Harbor Supply Menge: 12 Noch heute versenden Removed Gift wrap New Erstellen Abbrechen MyApp.exe 1.0 1.1 New Order Customer: Client: Harbor Supply Quantity: 12 Ship today Gift wrap Create Cancel Project Scan for Changes Neue Bestellung Kunde: Updated Harbor Supply Menge: 12 Noch heute versenden Removed Gift wrap New Erstellen Abbrechen
  2. Translated earlier MyApp.exe de\ DE MyApp.exe fr\ FR MyApp.exe Project Not Translated Imported DE FR MyApp.exe Dialogs Menus String Table Import from Localized Files Translated with another tool or long ago? Add your build: Lingobit finds the localized files and offers to import them. Import Translations from Localized Files Germande\MyApp.exe Frenchfr\MyApp.exe OK Cancel OK Translated earlier MyApp.exe de\ DE MyApp.exe fr\ FR MyApp.exe Project Not Translated Imported DE FR MyApp.exe Dialogs Menus String Table Import from Localized Files Translated with another tool or long ago? Add your build: Lingobit offers the import. Import Translations from Localized Files Germande\MyApp.exe Frenchfr\MyApp.exe OK Cancel OK

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.

Source code Build no source code · no rebuild Lingobit starts here What you ship EXE MyApp.exe DLL Core.dll Project MyApp.exe Dialogs Menus String Table Core.dll String Table Source code · Build Lingobit starts here EXE MyApp.exe DLL Core.dll Project MyApp.exe Dialogs Menus String Table Core.dll String Table

Lingobit does

  • Translates dialogs, menus, string tables, accelerators, version information, message tables, MFC combo box lists, toolbars, and ribbons.
  • 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

Release folderEXEMyApp.exeoriginalDEde\MyApp.exeFRfr\MyApp.exeJAja\MyApp.exeUse when: each language hasits own deployment package.At run timeNeue BestellungKunde:Menge:ErstellenThe application in German Release folderEXEMyApp.exeoriginalDEde\MyApp.exeFRfr\MyApp.exeJAja\MyApp.exeUse when: each language hasits own deployment package.Neue BestellungKunde:Menge:Erstellen

Resource-only DLLs

Release folderEXEMyApp.exeunchangedDLLMyAppDEU.dllDLLMyAppFRA.dllDLLMyAppJPN.dllUse when: one executable shouldsupport several languages.At run timeNeue BestellungKunde:Menge:ErstellenMFC loads it by itselfother Win32 code: your own Release folderEXEMyApp.exeunchangedDLLMyAppDEU.dllDLLMyAppFRA.dllDLLMyAppJPN.dllUse when: one executable shouldsupport several languages.Neue BestellungKunde:Menge:ErstellenMFC loads it by itselfother Win32 code: your own

Multi-language binaries

Release folderEXELocalized\MyApp.exeholdsDEFRJANot recommendedUse only for a specific packaging reason,and test the runtime behavior carefully.At run timeNeue BestellungKunde:Menge:ErstellenOne file, several languages Release folderEXELocalized\MyApp.exeholdsDEFRJANot recommendedUse only for a specific packaging reason,and test the runtime behavior carefully.Neue BestellungKunde:Menge:Erstellen

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.

WindowsGerman (Germany)de-DE MFC looks forMyAppDEU.dllloadedMyApp.exeif no DLL Your application Neue BestellungKunde:Menge: MFC loads the DLL in CWinApp::InitInstance; no code of yours is needed. WindowsGerman (Germany)de-DE MFC looks forMyAppDEU.dllloadedMyApp.exeif no DLL Neue BestellungKunde:Menge: MFC loads the DLL by itself;no code of yours is needed.
  • A localized EXE needs no loading code: the installer puts de\MyApp.exe in 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:

  1. List the languages you ship from the DLLs next to MyApp.exe.
  2. Read the saved choice or a command-line switch; otherwise leave the Windows language.
  3. Set it before CWinApp::InitInstance with SetThreadPreferredUILanguages.
  4. 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 call CWinApp::InitInstance in 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.

Troubleshooting.

Symptoms, causes, and what to do
SymptomLikely causeWhat to do
The application stays in English with resource-only DLLsThe 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 itCheck the folder and the name, call the base InitInstance, or load the DLL in your code
Text is cut off in a dialogThe translation is longer than the controlRun Validation: it reports truncated text in dialogs. Resize the control in the visual editor
Two menu items share a shortcutThe translation repeats an accelerator letterValidation reports duplicate and missing accelerators
The application crashes with one languageA translation breaks a placeholder or a resource the code depends onRun Validation; if the cause is not obvious, Crash Finder narrows it down to the translation (Enterprise)
Japanese text shows as question marksThe application is not Unicode, and Windows shows its text in the system code pageTest 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.
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.