我编写了两个程序,它们都是编译的,都包含通过.rc文件添加的"STRINGTABLES“资源。
因此,让我们将App #1称为"app1.exe“,将App #2称为"app2.exe”。
这是我的问题。在app2.exe中,我有一个字符串表,如下所示:
STRINGTABLE
{
1000, "Hello"
1001, "There"
}当我运行app1.exe时,我试图通过Win32 API UpdateResource()函数更新app2.exe中存储的资源。
我可以使用Delphi的LoadStr()函数从字符串中加载字符串,非常好。
我的问题是,我需要了解如何使用UpdateResource(),以便只更改该字符串中的字符串。因此,例如,我希望app1.exe将app2.exe的字符串表从上面看到的更改为:
STRINGTABLE
{
1000, "Thank"
1001, "You!"
}我很抱歉,我没有任何源代码,但我是从零开始,似乎无法理解这一点。
我正在使用XE7。
如果你们还需要做更多的事情,只要说出来,我会尽可能多地更新,但是就像我说过的,我只是刚开始学习TResourceStream和所有这些资源,所以我没有什么可展示的。我能告诉你的是,我对编程并不陌生。我很快就明白了。我已经创建了一个THandle,并获得了app1.exe来查看app2.exe的资源。我可以添加一些内容,但是当我尝试从一个String或TMemo组件中添加TEdit数据时,它会显示为app2.exe资源中一些奇怪的奇怪的中文字母。因此,我想知道如何格式化这些字符串,以便它们在资源和东西中正确地显示出来。
为了进一步了解这一点,当我运行app1.exe并尝试将字符串"Hello"输入app2.exe的可字符串时,它提供了以下内容:
00230BF8 00 00 00 00 ••••有什么线索吗?
运行程序后,我使用一个名为“资源黑客”的应用程序来检查资源。
发布于 2014-09-28 19:56:36
字符串表资源存储在16块中,每一项都用一个字长标记编写,UTF-16编码字符紧随其后。如果块中的项没有在原始RC文件中显式定义,那么它仍然存在于编译的资源中,但长度为0。
因此,让我们假设您已经仔细地选择了您的ID在同一个16组中。我将继续使用您提供的ID,并假设您希望在与EXE相同的目录中更新一个名为TestLib.dll的DLL;我还将假设我自己的地区(英式英语)--您需要根据需要更改MAKELANGID参数:
const
LibName = 'TestLib.dll';
ID_FIRST = 1000;
ID_SECOND = 1001;
function StringIDToGroupID(ID: UINT): UINT; inline;
begin
Result := (ID shr 4) + 1;
end;
procedure UpdateStrings(const NewFirst, NewSecond: string);
var
Handle: THandle;
GroupID: UINT;
Stream: TCustomMemoryStream;
GroupStrings: array[0..15] of string;
StrLen: Word;
I: Integer;
begin
GroupID := StringIDToGroupID(ID_FIRST);
//get existing data...
Handle := LoadLibraryEx(LibName, 0, LOAD_LIBRARY_AS_DATAFILE);
if Handle = 0 then RaiseLastOSError;
try
Stream := TResourceStream.CreateFromID(Handle, GroupID, RT_STRING);
try
for I := Low(GroupStrings) to High(GroupStrings) do
begin
Stream.ReadBufferData(StrLen);
SetLength(GroupStrings[I], StrLen);
Stream.ReadBuffer(PChar(GroupStrings[I])^, StrLen * SizeOf(Char));
end;
finally
Stream.Free;
end;
finally
FreeLibrary(Handle);
end;
//update the strings we're interested in...
GroupStrings[ID_FIRST mod Length(GroupStrings)] := NewFirst;
GroupStrings[ID_SECOND mod Length(GroupStrings)] := NewSecond;
Stream := TMemoryStream.Create;
try
for I := Low(GroupStrings) to High(GroupStrings) do
begin
StrLen := Length(GroupStrings[I]);
Stream.WriteData(StrLen);
Stream.WriteBuffer(PChar(GroupStrings[I])^, StrLen * SizeOf(Char));
end;
//update DLL...
Handle := BeginUpdateResource(LibName, False);
if Handle = 0 then RaiseLastOSError;
try
UpdateResource(Handle, RT_STRING, PChar(GroupID),
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK), Stream.Memory, Stream.Size);
finally
EndUpdateResource(Handle, False);
end;
finally
Stream.Free;
end;
end;https://stackoverflow.com/questions/26087756
复制相似问题