Delphi 如何更改存储在.exe文件中的StringTable值

Delphi 如何更改存储在.exe文件中的StringTable值,delphi,winapi,delphi-xe7,Delphi,Winapi,Delphi Xe7,我已经编写了两个程序,它们都经过编译,都包含通过.rc文件添加的“STRINGTABLES”资源 那么,让我们把App#1称为“app1.exe”,把App#2称为“app2.exe” 这是我的问题。在app2.exe中,我有一个字符串表,如下所示: STRINGTABLE { 1000, "Hello" 1001, "There" } 运行app1.exe时,我试图通过Win32 APIUpdateResource()函数更新存储在app2.exe中的资源 我可以使用Delphi的LoadS

我已经编写了两个程序,它们都经过编译,都包含通过.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()
函数从stringtable加载字符串

我的问题是我需要了解如何使用
UpdateResource()
,以便只更改该stringtable中的字符串。例如,我希望app1.exe将app2.exe的字符串表从上面看到的更改为:

STRINGTABLE
{
1000, "Thank"
1001, "You!"
}
很抱歉,我没有任何源代码,但我是从零开始的,似乎无法解决这个问题

我正在使用RAD Studio XE7

如果你们还需要更多的信息,就这么说吧,我会尽可能多地更新,但就像我说的,我刚刚开始学习
TResourceStream
和所有这些资源,所以我没有太多要展示的内容。我只能告诉你,我对编程并不陌生。我很快就明白了。我已经创建了一个
THandle
,并让app1.exe查看app2.exe的资源。我可以向它添加内容,但当我尝试从
TEdit
TMemo
组件添加
String
数据时,它似乎在app2.exe的资源中显示为一些奇怪的中文字母。所以我想知道如何格式化这些字符串,以便它们正确地显示在资源和内容中

为了进一步说明这一点,当我运行app1.exe并尝试在app2.exe的stringtable中输入字符串
“Hello”
时,它给出了以下信息:

00230BF8  00 00 00 00                                       ••••
有什么线索吗


运行程序后,我正在使用一个名为“资源黑客”的应用程序来检查资源。

字符串表资源以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;

搜索有关执行此操作的教程。有人想知道,如果你想让字符串可变,为什么要把它们放在可执行文件中。否则,如果你想得到代码方面的帮助,你就需要展示它——没关系。如果你不能在问题中显示代码,那么我也帮不了你。谢谢你编辑我的问题雷米:)现在至少人们可以更好地理解它了,哈哈。。。很抱歉格式太糟糕。@Remy您的标记编辑不好。请不要删除delphi标签,它应该包含在所有delphi问题中。非常感谢您的详细解释:)我可以按照自己的喜好进行编辑。我现在就接受你的回答,伙计,我真是太感谢你了!非常感谢:)