>我在我的 Win32 应用程序中定义了一个字符串表:
STRINGTABLE
BEGIN
IDS_STRING101 "myString1"
IDS_STRING102 "myString2"
IDS_STRING103 "myString3"
END
由于我希望所有这些字符串都成为数组的一部分,是否可以遍历此表?由于LoadStringA()
需要宏IDS_STRING101等,因此似乎不可能遍历它。
举一个实际的例子,我将如何以编程方式将这些字符串移动到字符串数组(char*
C 中的数组,std::string
C++ 中的数组(,而不使用使用第二个参数IDS_STRINGXXX
编写长重复的LoadStringA()
调用代码的明显方法?如果可能的话,我希望将来能够向此表添加更多字符串,而无需修改代码中的任何内容。
没有 API 来枚举字符串表的各个字符串。您必须将整个字符串表资源作为一个整体加载到内存中,然后根据文档手动解析它。
更简单的解决方案是在循环中调用LoadStringA()
,因为您的字符串 ID 是连续的,例如:
char myStrings[3][16] = {};
for (int idx = 0; idx < 3; ++idx) {
LoadStringA(hInstance, IDS_STRING101 + idx, myStrings[idx], 16);
}
我将如何以编程方式将这些字符串移动到字符串数组中
您可以在函数或类中隐藏繁琐的重复。
类示例:
#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
。