【问题标题】:How to use MFC Resource id stored as string如何使用存储为字符串的 MFC 资源 ID
【发布时间】:2014-08-13 04:13:11
【问题描述】:

我正在开发一个 MFC 应用程序,其中我在 .rc 文件中定义了菜单。我需要在运行时删除一些在 xml 文件中定义的菜单项。

菜单 ID 以字符串形式存储在 xml 中,如下所示

<exclusionmenu>ID_FILE_NEW</exclusionmenu>
<exclusionmenu>ID_FILE_OPEN</exclusionmenu>

从 xml 中检索菜单 ID 作为字符串,

RemoveMenu 函数需要 UINT(菜单 ID),

如何将xml中定义的菜单id字符串转换为uint菜单id

注意:这不是直接 cstring 到 uint 的转换,ID_FILE_NEW 是宏,它有 int 值。

【问题讨论】:

  • 到底为什么要使用 XML 文件来定义资源?为什么不能只使用资源 ID?
  • 我的应用程序有很多菜单;菜单需要在 xml 配置决定的运行时删除。因此,无需更改代码即可更改删除项目。

标签: string macros mfc resources uint


【解决方案1】:

资源标识符的符号名称在头文件中定义,默认情况下是Resource.h。在源代码和资源脚本中,符号名称被预处理器替换为它们各自的数值。编译开始时,符号信息已经没有了。

要实现使用符号名称进行配置的方案,您必须提取并保留符号名称和资源标识符之间的映射以供以后在运行时使用,或者在部署之前将该映射应用于配置文件。以下是可能的选项列表:

使用关联容器并在应用程序启动时填充它:合适的容器是std::map&lt;std::string, unsigned int&gt;。使用 C++11 的 list initialization 功能可以方便地填充此容器:

static std::map<std::string, unsigned int> IdMap = {
    {"ID_FILE_NEW", ID_FILE_NEW},
    {"ID_FILE_OPEN", ID_FILE_OPEN},
    // ...
}

在运行时,您可以使用此容器来检索给定其符号常量的资源标识符:

unsigned int GetId(const std::string& name) {
    if (IdMap.find(name) == IdMap.end())
        throw std::runtime_error("Unknown resource identifier.");
    return IdMap[name];
}

这种方法的缺点是您必须保持IdMap 和资源同步。每当添加、修改或删除资源时,都必须更新容器内容以反映所做的更改。

解析 Resource.h 并存储映射: 包含符号标识符名称的头文件具有相当简单的结构。定义符号常量的代码行通常具有以下布局:

\s* '#' \s* 'define' \s+ <name> \s+ <value> <comment>?

提取映射的解析器并不像看起来那么难实现,并且应该在构建过程中的适当时间运行。提取映射后,可以将其存储在任意格式的文件中,例如INI file。该文件可以与应用程序一起部署,也可以作为资源编译到二进制映像中。在应用程序启动时,内容被读回,并用于构造上一段中描述的映射。与之前的方案相比,解析Resource.h文件不需要在资源变化时手动更新代码。

解析 Resource.h 并转换配置 XML 文件: 与之前的解决方案一样,此选项也需要解析 Resource.h 文件.使用此信息,然后可以转换配置 XML 文件,在部署之前用符号名称替换它们的数字对应项。这也需要额外的工作。但是,一旦完成,该过程就可以自动化,并验证结果以保持一致性。在运行时,您可以简单地读取 XML 并随时获得数字标识符。

【讨论】:

    【解决方案2】:

    您的方案可行的唯一方法是当您将 Resoutce.h 与您的应用程序一起分发时,并且您有逻辑在启动时将 Resource.h 解析为包含 ID_* 名称及其值的表。

    【讨论】:

      【解决方案3】:

      你不能,字符串形式在编译时“丢失”了,它是一个预处理器标记。您可以存储菜单项的字符串变体:在代码中的某处,有 std::map 并用值填充它: menu_ids["ID_FILE_NEW"] = ID_FILE_NEW;然后你调用 RemoveMenu(menu_ids[string_from_xml]);

      【讨论】:

      猜你喜欢
      • 2021-08-24
      • 2014-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-27
      相关资源
      最近更新 更多