1

是否可以在运行时将字符串添加到 STRINGTABLE 资源?我有一个连接到主机应用程序的插件,它需要使用 LoadString 方法传递的字符串。就我而言,我只能在运行时准备数据(通常在启动时准备一次)。我已经在准备 DLGTEMPLATE 结构,是否有类似的方法来处理 STRINGTABLE?还有其他解决方案吗?

谢谢,

4

1 回答 1

0

正如 enhzflep 建议的那样,我更新了一个单独的 PE 文件。需要一些尝试和错误才能正确更新字符串,所以我在这里发布我的解决方案。

注意事项:我正在按顺序编写字符串。用 16 个字符串的块更新资源很重要,因此编写具有预定义 ID 的字符串将涉及编写一些空字符串。

const int RESOURCE_STRING_START = 1 << 14; /// custom start ID value
std::vector<std::wstring> m_resource_strings;

/// add strings ///

HANDLE lib_handle = BeginUpdateResource( library_name, TRUE);

size_t string_section_size = 0;
for (int i = 0; i < m_resource_strings.size(); i++)
    string_section_size += m_resource_strings[i].length() * sizeof(WCHAR);

HGLOBAL heap = GlobalAlloc(GMEM_ZEROINIT, string_section_size); 
if (!heap) {
    return false;
}
/// Create temporary memory pool ///
WORD* heap_start = (WORD*)GlobalLock(heap);
if (!heap_start) {
    return false;
}
WORD* pos = NULL;

for (int i = 0; i < m_resource_strings.size(); i+=16)
{
    pos = heap_start;
    const int section = 1 + ((RESOURCE_STRING_START + i) >> 4);
    for (int j = 0; j < 16; j++)
    {
        if ( i+j < m_resource_strings.size() ) {
            std::wstring& str = m_resource_strings[j+i];
            *pos++ = str.length(); /// Write string length
            memcpy( pos, str.data(), str.length() * sizeof(WCHAR) ); /// Copy string
            pos += str.length();
        }
        else *pos++ = 0;
    }
    if (!UpdateResource(lib_handle, RT_STRING, (LPTSTR)(ULONG_PTR)section, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), heap_start, DWORD(pos) - DWORD(heap_start) ))
    {
        GlobalFree(heap);
        return false;
    }
}
GlobalFree(heap);

if (!EndUpdateResource( lib_handle, FALSE )) {
    return false;
}
于 2013-06-24T08:37:45.927 回答