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

2024-02-06

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

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

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

我尝试了几种方法,例如制作新的资源文件并将原始的德语菜单复制到新文件中。但我收到了几个错误,例如“输入合法的资源 ID”。


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

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

Steps

  1. 通过 MFC 应用程序向导创建的项目已经包含一个空的 .rc2 文件,我们可以将其用作“主”.rc2 文件。否则遵循文档 https://learn.microsoft.com/en-us/previous-versions/6e7446zd(v=vs.140)或者使用向导创建一个新的 MFC 应用程序来剖析如何包含 .rc2 文件。
  2. 在主 .rc2 文件中添加#include对于每个特定于语言的 .rc2 文件:

    #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() https://learn.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-findresourceexa.

包括标准MFC资源

无需再费周折,标准 MFC 资源 https://learn.microsoft.com/en-us/cpp/mfc/tn023-standard-mfc-resources?view=vs-2017将仅包含在项目资源属性中配置的“主”语言中。

在我使用此方法的项目中,我不需要标准 MFC 资源。以下只是一个untested想法如何可能做到这一点。

在每个非“主”语言的特定于语言的 .rc2 文件中,添加#includes 为 MFC 标准资源LANGUAGE莱恩岛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是为了规避标准 MFC 资源文件的包含保护,这通常会阻止多次包含。在我们的例子中,这是可以的,因为资源最终会出现在可执行文件的不同语言资源部分中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 将集合绑定到自定义控件属性

    我没有运气尝试将数据集合绑定到我的自定义控件的属性 我已经实现了该控件的字符串属性的机制 在此处提供了一些帮助 并期望集合类型同样简单 但是我无法让它再次工作 这是我的自定义控件视图
  • 有没有快速创建集合的方法?

    目前我正在创建一个像这样的新集 std set a s s insert a1 s insert a2 s insert a3 s insert a10 有没有办法创建s在一行 int myints 10 20 30 40 50 std s
  • 在实体框架拦截器中向 DbScanExpression 添加内部联接

    我正在尝试使用实体框架 CommandTree 拦截器通过 DbContext 向每个查询添加过滤器 为了简单起见 我有两个表 一个称为 User 有两列 UserId 和 EmailAddress 另一个称为 TenantUser 有两列
  • 更改 Qt OpenGL 窗口示例以使用 OpenGL 3.3

    我正在尝试更改 Qt OpenGL 示例以使用更现代的 opengl 版本 330 似乎合适 所以我做了 在 main cpp 上设置版本和配置文件 设置着色器版本 更改着色器以使用统一 它现在构建没有任何错误 但我只看到一个空白窗口 我错
  • 根据 N 个值中最小的一个返回不同的结果

    不确定如何使标题更具描述性 所以我只是从一个例子开始 我使用下面的代码位 它从枚举中选择一个方向 具体取决于四个轴中哪一个与给定方向相比形成最小角度 static Direction VectorToDirection Vector2 di
  • 与 Qt 项目的静态链接

    我有一个在 Visual Studio 2010 Professional 中构建的 Qt 项目 但是 当我运行它 在调试或发布模式下 时 它会要求一些 Qt dll 如果我提供 dll 并将它们放入 System32 中 它就可以工作 但
  • 找不到 assimp-vc140-mt.dll ASSIMP

    我已经从以下位置下载了 Assimp 项目http assimp sourceforge net main downloads html http assimp sourceforge net main downloads html Ass
  • 时间:2019-03-17 标签:c#ThreadSafeDeepCopy

    我一直在阅读很多其他问题以及大量谷歌搜索 但我一直无法找到明确的解决方案 根据我读过的一些最佳实践 类的静态方法应该创建线程安全的 并且实例成员应该将线程安全留给消费者 我想为该类实现深度复制方法 该类本身还有其他引用类型成员 有没有什么方
  • 在 JSQMessagesViewController 中显示 LocationMediaItem

    我刚刚尝试实施LocationMediaItem in my Xamarin iOS应用程序使用JSQMessagesViewController 一切都很顺利 唯一的问题是UICollectionView应该显示位置的单元格永远停留在加载
  • 如何在服务器端按钮点击时关闭当前标签页?

    我尝试在确认后关闭当前选项卡 因此我将以下代码放在确认按钮的末尾 但选项卡没有关闭 string jScript ClientScript RegisterClientScriptBlock this GetType keyClientBl
  • 将二进制数据从 C# 上传到 PHP

    我想将文件从 Windows C 应用程序上传到运行 PHP 的 Web 服务器 我知道 WebClient UploadFile 方法 但我希望能够分块上传文件 以便我可以监控进度并能够暂停 恢复 因此 我正在读取文件的一部分并使用 We
  • 无法在内存位置找到异常源:cudaError_enum

    我正在尝试确定 Microsoft C 异常的来源 test fft exe 中 0x770ab9bc 处的第一次机会异常 Microsoft C 异常 内存位置 0x016cf234 处的 cudaError enum 我的构建环境是 I
  • 运行选定的代码生成器时出错:“未将对象引用设置到对象的实例。”错误?

    我已经尝试了所有解决方案 例如修复 VS 2013 但没有用 当您通过右键单击控制器文件夹来创建控制器并添加控制器时 然后右键单击新创建的控制器的操作并选择添加视图 当我尝试创建视图时 就会发生这种情况 它不是一个新项目 而是一个现有项目
  • 如何通过 JsonConvert.DeserializeObject 在动态 JSON 中使用 null 条件运算符

    我正在使用 Newtonsoft 反序列化已知的 JSON 对象并从中检索一些值 如果存在 关键在于对象结构可能会不断变化 因此我使用动态来遍历结构并检索值 由于对象结构不断变化 我使用 null 条件运算符来遍历 JSON 代码看起来像这
  • 如何在c的case语句中使用省略号?

    CASE expr no commas ELLIPSIS expr no commas 我在c的语法规则中看到了这样的规则 但是当我尝试重现它时 int test float i switch i case 1 3 printf hi 它失
  • ASP.NET MailMessage.BodyEncoding 和 MailMessage.SubjectEncoding 默认值

    很简单的问题 但我在 MSDN 上找不到答案 查找 ASP NET 将用于的默认值 MailMessage BodyEncoding and MailMessage SubjectEncoding 如果你不在代码中设置它们 Thanks F
  • IEnumerable.Except 不起作用,那么我该怎么办?

    我有一个 linq to sql 数据库 非常简单 我们有 3 个表 项目和用户 有一个名为 User Projects 的连接表将它们连接在一起 我已经有了一个获得的工作方法IEnumberable
  • 了解使用 Windows 本机 WPF 客户端进行 ADFS 登录

    我已经阅读了大量有关 ADFS 与 NodeJS Angular 或其他前端 Web 框架集成以及一般流程如何工作的文献 并通过 Auth0 Angular 起始代码构建了概念证明 但我不明白如何这可以与本机 WPF Windows 应用程
  • 使用taskkill停止Windows服务

    我需要帮助来使用 C 终止 Windows 服务 现在要终止该服务 请使用以下选项 从命令 sc queryex ServiceName 发现后PID服务的 taskkill pid 1234 exemple f 为了便于阅读 但如果您明白
  • ASP.NET Core MVC 视图组件搜索路径

    在此处的文档中 https learn microsoft com en us aspnet core mvc views view components view aspnetcore 2 2 https learn microsoft

随机推荐