You can embed multiple language resources in a single .exe file without having to use resource DLLs. There is no support for this use case by the Visual Studio resource editor, so resource scripts must be edited manually, using a text editor.
To define the resources, use .rc2 files which the Visual Studio resource editor won't try to modify. Make sure to store the .rc2 files with Unicode (UTF-16 LE) encoding and always end them with a line break, otherwise the resource compiler will fail.
Steps
- A project created through the MFC application wizard already includes an empty .rc2 file, which we can use as our "main" .rc2 file. Otherwise follow the documentation or create a new MFC application using the wizard to dissect how the .rc2 file is included.
In the main .rc2 file add an #include
for each language-specific .rc2 file:
#include "lang_en.rc2"
#include "lang_de.rc2"
// Restore default language for resources included after current file
LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
Create the language-specific .rc2 files. Each file must start with LANGUAGE <LANGID>, <SUBLANGID>
to indicate the language of the following resources:
lang_en.rc2
LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
STRINGTABLE
BEGIN
IDS_STRING1 "Stack Overflow"
IDS_STRING2 "Stack Overflow is a privately held website, the flagship site of the Stack Exchange Network, created in 2008 by Jeff Atwood and Joel Spolsky."
END
lang_de.rc2
LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
STRINGTABLE
BEGIN
IDS_STRING1 "Stapelüberlauf"
IDS_STRING2 "Stack Overflow (englisch für Stapelüberlauf) ist eine Internetplattform, auf der angemeldete Benutzer Fragen zum Thema Softwareentwicklung stellen können."
END
Build the executable and examine it in a resource editor to see if the resources are actually included for multiple languages. Instead of using a resource editor, you can also open the .exe file in Visual Studio to examine its resources. For instance, the demo .exe I build for this answer, looks like this, when opened in Visual Studio:

In the code you can load resources as usual, Windows will automatically load the language resource that best matches the current user locale. If it doesn't find a match, it falls back to English.
If you want to explicitly load a resource for a given language, you can do this by using the resource functions that have a language parameter, e. g. FindResourceEx()
.
Including standard MFC resources
Without further ado, standard MFC resources will be included only in the "main" language that is configured in the resource properties of the project.
In the projects where I have used this approach, I had no need for the standard MFC resources. The following is just an untested idea how it could possibly be done.
In each language-specific .rc2 file that is not the "main" language, add #include
s for the MFC standard resources after the LANGUAGE
line, e. g.:
LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
#ifdef __AFXRES_RC__
#undef __AFXRES_RC__ // To be able to include multiple language versions of afxres.rc
#endif
#include "l.deu\afxres.rc" // Standard MFC resources
STRINGTABLE
BEGIN
IDS_STRING1 "Stapelüberlauf"
IDS_STRING2 "Stack Overflow (englisch für Stapelüberlauf) ist eine Internetplattform, auf der angemeldete Benutzer Fragen zum Thema Softwareentwicklung stellen können."
END
The #undef
is there to circumvent the include guard of the standard MFC resource file, which normally prevents multiple includes. In our case this is OK, because the resources will end up in different language resource sections of the executable.
#ifdef APPLANG=EN
is not a valid preprocessor, nor is#else if
. You can try#ifdef APPLANG_EN ...
and#elif APPLANG_DE
and set the value forIDR_RIBBON_TARGET
instead of the whole line code – Barmak ShemiraniLANGUAGE <LANGID>, <SUBLANGID>
. These are all#include
'd in one main .rc2 file. The .rc2 files are used so the Visual Studio resource editor won't create a mess. Make sure to store the .rc2 files as Unicode (UTF-16 LE). – zett42