1

実行時にSTRINGTABLEリソースに文字列を追加することは可能ですか? LoadString メソッドで文字列が配信されることを期待するホスト アプリケーションに接続されているプラ​​グインがあります。私の側では、実行時にのみデータを準備できます (通常は起動時に 1 回)。私は既にその場で DLGTEMPLATE 構造を準備していますが、STRINGTABLE を扱う同様の方法はありますか? 他の解決策はありますか?

ありがとう、

4

1 に答える 1

0

enhzflep が示唆したように、別の PE ファイルを更新しました。文字列を正しく更新するには試行錯誤が必要だったので、ここに私の解決策を投稿します。

1 つのメモ: 文字列を順番に書き込んでいます。リソースを 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 に答える