【问题标题】:Iterate through resource string table遍历资源字符串表
【发布时间】:2020-06-01 20:18:55
【问题描述】:

我在我的 Win32 应用程序中有一个这样定义的字符串表:

STRINGTABLE
BEGIN
    IDS_STRING101           "myString1"
    IDS_STRING102           "myString2"
    IDS_STRING103           "myString3"
END

由于我希望所有这些字符串都成为数组的一部分,是否可以遍历该表?由于LoadStringA() 需要宏IDS_STRING101 等,因此似乎无法遍历它。

举一个实际的例子,我如何以编程方式将这些字符串移动到字符串数组(C 中的char* 数组,C++ 中的std::string 数组)而不使用明显的方式来编写LoadStringA() 的长重复代码调用第二个参数IDS_STRINGXXX?如果可能的话,我希望将来能够在不修改代码中的任何内容的情况下向该表中添加更多字符串。

【问题讨论】:

  • 不确定,您真正想要在这里完成什么。但是没有什么能阻止您在 resource.h 文件中定义符号常量,例如 IDS_STRING_FIRSTIDS_STRING_LAST
  • @RemyLebeau 我正在考虑为LoadString() 创建一个循环,但是我应该如何知道要在循环中读取哪个字符串?是否可以遍历常量? (根据我的阅读,我必须将IDS_STRINGXXX 传递给LoadString()
  • LoadString 需要一个数值。将1 添加到数字是微不足道的。
  • @edw 这不是假设。这是一个要求。可以轻松安排的要求。
  • @EdwardKarak ...如果想加载不连续的字符串,可以将循环替换为for(UINT id : {IDS_STRING101,IDS_STRING102,IDS_STRING103}) { LoadString(...,id,...); }

标签: c++ c winapi


【解决方案1】:

没有 API 可以枚举字符串表的各个字符串。您必须将整个字符串表资源作为一个整体加载到内存中,然后根据documentation 手动解析它。

更简单的解决方案是在循环中调用LoadStringA(),因为您的字符串 ID 是连续的,例如:

char myStrings[3][16] = {};
for (int idx = 0; idx < 3; ++idx) {
    LoadStringA(hInstance, IDS_STRING101 + idx, myStrings[idx], 16);
}

【讨论】:

    【解决方案2】:

    如何以编程方式将这些字符串移动到字符串数组中

    您可以在函数或类中隐藏繁琐的重复。

    类示例:

    #include <stdexcept>
    #include <string>
    #include <unordered_map>
    
    class StringLoader {
    public:
        StringLoader(HINSTANCE inst) : hInstance(inst) {}
    
        std::pair<UINT,std::string> operator()(UINT uID) {
            const char* resptr;
            UINT len = LoadStringA(hInstance, uID, reinterpret_cast<LPSTR>(&resptr), 0);
            if(len==0) throw std::runtime_error("resource not found: "+std::to_string(uID));
            return {uID, {resptr, resptr+len}};
        }
    private:
        HINSTANCE hInstance;
    };
    
    //... then use it:
    
        StringLoader l(the_instance);
        std::unordered_map<UINT, std::string> resources {
            l(IDS_STRING101),
            l(IDS_STRING102),
            l(IDS_STRING103)
        };
    

    您现在将拥有一个可以迭代或用作查找表的地图。如果只需要字符串,可以将地图替换为vector,并相应调整StringLoader

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-15
      • 1970-01-01
      • 2014-09-19
      相关资源
      最近更新 更多