使用UpdateResource更新string表

我问这里的问题 – 通过UpdateResource更新STRING TABLE(添加多个string)

现在我又问了一遍,因为这次我可以在这个问题上增加更多的细节。

我一直在尝试这个过去的一天,或没有真正有用的东西。 我想要的结果是这样的(我手动添加MSVS中的string):正如你可以看到,多个条目,它是“干净”,可以很容易地被程序访问! 在这里输入图像说明

现在,我的来源:

wstring buffer[5] = {L" Meow",L" I",L" Am",L" A",L" Dinosaur"}; // ignore the string if (HANDLE hRes = BeginUpdateResource("Output.exe",TRUE)) { for (int i = 0; i < 5; i++) { wchar_t * temp; temp = new wchar_t[(buffer[i].length()+1)]; wcscpy(temp,buffer[i].c_str()); wcout << temp << endl; UpdateResource(hRes,RT_STRING,MAKEINTRESOURCE(1),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), temp, 48); //buffer[i].length()+1 delete[] temp; } EndUpdateResource(hRes,FALSE); } 

生产: 在这里输入图像说明

这是错误的,因为它似乎只是将最后一个string添加到表中,而不是之前的string!

当我尝试修改源,所以MAKEINTRESOURCE(1)现在是“MAKEINTRESOURCE(i)”,结果如下图所示: http://gyazo.com/5fa7a6682d5da2def4683227533b2755.pnghttp://gyazo.com/e77f6e90cb3dbfe21d07b3d55c931acb.pnghttp://gyazo.com/2e632768e2cdfcea8ab9cd08caea9cc8.pnghttp://gyazo.com/f9dcd68c671923d8faefce76877bc3be.png

事实上,它添加了所有的string,但它似乎创build了各种不是所需的string表。 虽然我注意到ID在每张图片中都增加了16,这可能可以解释一些事情。 基本上,我想string被格式化为第一张图片(多个string),但没有真正的想法如何做到这一点。

谢谢您的帮助。

Solutions Collecting From Web of "使用UpdateResource更新string表"

字符串资源不同于任何其他资源格式。 它们不是作为单独的条目存储,而是被分组成每组16个字符串。 第一组存储字符串0到15,第二组存储字符串16到31,依此类推。 在上面的屏幕截图中,组显示为左侧树视图中父级下的第一级。

字符串资源也是不同的,因为它们被存储为统计的Unicode字符串(不带零终止符),而不是零终止的C字符串。 因此,例如C字符串'T' 'e' 's' 't' '\0'将被存储为0004 0054 0065 0073 0074 ,其中第一个WORD表示长度,其余4个WORD表示Unicode字符。

这种资源格式的结果是,如果组内的字符串ID中存在空白,则缺少的字符串必须用零长度的字符串来解释,或者简单地以0000资源格式。 因此,如果您的字符串表中有ID为2和5的字符串,则会有一个包含16个条目的组(1): 0000 0000 <string 2> 0000 0000 <string 5> 0000 00000000

还有一个需要的信息,即在调用UpdateResource要为lpName参数传递哪个资源ID:由于字符串资源组只能作为一个整体进行更新,因此必须提供组ID,其中第一个组具有ID 1.使用groupID = ( strID >> 4 ) + 1计算字符串ID中的组ID,而组内相对(从零开始)的偏移量是strOffset = strID % 16 如果您查看通过MAKEINTRESOURCE(1)传递的结果,现在可以看到为什么它在组1中ID为0。

把所有的部分放在一起,你可以使用下面的代码更新一个字符串资源:

 void ReplaceStringTable() { HANDLE hRes = BeginUpdateResource( _T( "Output.exe" ), TRUE ); if ( hRes != NULL ) { wstring data[] = { L"", // empty string to skip string ID 0 L"Raymond", L"Chen", L"is", L"my", L"Hero!", // remaining strings to complete the group L"", L"", L"", L"", L"", L"", L"", L"", L"", L"" }; vector< WORD > buffer; for ( size_t index = 0; index < sizeof( data ) / sizeof( data[ 0 ] ); ++index ) { size_t pos = buffer.size(); buffer.resize( pos + data[ index ].size() + 1 ); buffer[ pos++ ] = static_cast< WORD >( data[ index ].size() ); copy( data[ index ].begin(), data[ index ].end(), buffer.begin() + pos ); } UpdateResource( hRes, RT_STRING, MAKEINTRESOURCE( 1 ), MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), reinterpret_cast< void* >( &buffer[ 0 ] ), buffer.size() * sizeof( WORD ) ); EndUpdateResource( hRes, FALSE ); } }