在不使用资源 DLL 的情况下向 MFC 项目添加第二种语言

Add a second language to a MFC project without using resource DLLs

我有一个非常小的应用程序,它是用带有德语菜单的 MFC 制作的。现在我也被要求制作英文版。 但目标是 不使用其他语言 DLL。最后应该只有两个 .exe 文件(德语和英语)。 你知道任何分步手册如何为英语对话添加第二个资源文件(如果需要)以及如何在我的 C++ 代码中使用它们吗? 我的想法是使用预处理器指令:

#ifdef APPLANG=EN
    m_wndRibbonBar.LoadFromResource(IDR_RIBBON_EN);
#else if
    m_wndRibbonBar.LoadFromResource(IDR_RIBBON);
#endif

这样做是个好主意吗? 以及简单复制现有资源文件并修改成英文的正确步骤是什么?

我已经尝试了几种方法,比如制作一个新的资源文件并将原来的德语菜单复制到新文件中。但是我得到了几个错误,比如 "Enter a legal resource ID".

您可以在单个 .exe 文件中嵌入多种语言资源,而无需使用资源 DLL。 Visual Studio 资源编辑器不支持此用例,因此必须使用文本编辑器手动编辑资源脚本。

要定义资源,请使用 Visual Studio 资源编辑器不会尝试修改的 .rc2 文件。确保使用 Unicode (UTF-16 LE) 编码存储 .rc2 文件,并始终 以换行符 结束它们,否则资源编译器会失败。

步骤

  1. 通过 MFC 应用程序向导创建的项目已经包含一个空的 .rc2 文件,我们可以将其用作我们的 "main" .rc2 文件。否则按照 the documentation 或使用向导创建一个新的 MFC 应用程序来剖析如何包含 .rc2 文件。
  2. 在主 .rc2 文件中为每个语言特定的 .rc2 文件添加一个 #include

    #include "lang_en.rc2"
    #include "lang_de.rc2"
    
    // Restore default language for resources included after current file
    LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
    
  3. 创建语言特定的 .rc2 文件。每个文件必须以 LANGUAGE <LANGID>, <SUBLANGID> 开头,以指示以下资源的语言:

    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
    
  4. 构建可执行文件并在资源编辑器中检查它以查看资源是否实际包含在多种语言中。除了使用资源编辑器,您还可以打开 Visual Studio 中的 .exe 文件来检查其资源。例如,我为此答案构建的演示 .exe 在 Visual Studio:

    中打开时看起来像这样

在您可以照常加载资源的代码中,Windows会自动加载与当前用户语言环境最匹配的语言资源。如果找不到匹配项,它将回退到英语。

如果您想为给定语言显式加载资源,可以使用具有语言参数的资源函数来实现,例如。 G。 FindResourceEx().

包括标准 MFC 资源

事不宜迟,standard MFC resources 将仅包含在项目资源属性中配置的 "main" 语言中。

在我使用这种方法的项目中,我不需要标准的 MFC 资源。以下只是一个未经测试的想法。

在每个非 "main" 语言的特定语言 .rc2 文件中,在 LANGUAGE 行之后为 MFC 标准资源添加 #includes,例如。 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

#undef 用于规避标准 MFC 资源文件的包含保护,这通常会阻止多个包含。在我们的例子中,这是可以的,因为资源最终会出现在可执行文件的不同语言资源部分。