delphi - 在 Delphi 中创建和加载资源

标签 delphi resources

嗨,我有一个程序,当加载按钮时,在应用程序本身中手动创建资源(在本例中是图像),然后读取资源以在 timage 中显示。El 的问题是,它似乎创建了资源很好,但是当我想加载资源时却说在你寻找时找不到它。

代码。

procedure StringtoRes(const FileName: string; Inputstream: TMemoryStream);
var
  hUpdate: THandle;
begin
  hUpdate := BeginUpdateResource(PChar(FileName), True);
  try
    UpdateResource(hUpdate, RT_RCDATA, 'ID', LANG_NEUTRAL, Inputstream.Memory,
      Inputstream.Size);
  finally
    EndUpdateResource(hUpdate, False);
  end;
end;

procedure TForm1.btnTestClick(Sender: TObject);
var
  MemStr: TMemoryStream;
  FileName: string;

var
  RStream: TResourceStream;
  JPEGImage: TJPEGImage;
begin

  FileName := 'c:/test/test.jpg';

  MemStr := TMemoryStream.Create;
  MemStr.LoadFromFile(FileName);
  MemStr.Seek(0, soFromBeginning);
  StringtoRes(paramstr(0), MemStr);
  MemStr.Free;


  Sleep(3000);


  RStream := TResourceStream.Create(HInstance, 'ID', RT_RCDATA);
  JPEGImage := TJPEGImage.Create;
  JPEGImage.LoadFromStream(RStream);
  Image1.Picture.Graphic := JPEGImage;

  JPEGImage.Free;
  RStream.Free;

end;

当我解决这个问题时?

最佳答案

通常,正在运行的进程无法更新自己的资源,因为其可执行文件被锁定且不可写。要执行您正在尝试的操作,您应该将资源移动到单独的 DLL,然后您可以在需要加载其资源时通过 LoadLibrary() 动态加载 DLL,并通过 卸载它FreeLibrary() 当您需要更新其资源时。

var
  hResLib: THandle = 0;

procedure TForm1.btnTestClick(Sender: TObject);
var
  ResFileName: string;
  MemStr: TMemoryStream;
  RStream: TResourceStream;
  JPEGImage: TJPEGImage;
begin
  ResFileName := ExtractFilePath(ParamStr(0)) + 'myres.dll';

  if hResLib <> 0 then
  begin
    FreeLibrary(hResLib);
    hResLib := 0;
  end;

  MemStr := TMemoryStream.Create;
  try
    MemStr.LoadFromFile('c:/test/test.jpg');
    MemStr.Position := 0;
    StringtoRes(ResFileName, MemStr);
  finally
    MemStr.Free;
  end;

  Sleep(3000);

  hResLib := LoadLibrary(ResFileName);
  Win32Check(hResLib <> 0);

  RStream := TResourceStream.Create(hResLib, 'ID', RT_RCDATA);
  try
    JPEGImage := TJPEGImage.Create;
    try
      JPEGImage.LoadFromStream(RStream);
      Image1.Picture.Graphic := JPEGImage;
    finally
      JPEGImage.Free;
    end;
  finally
    RStream.Free;
  end;
end;

此外,在调用 UpdateResource() 之前,您不会检查 BeginUpdateResource() 的返回值以确保它确实成功。

procedure StringtoRes(const FileName: string; Inputstream: TMemoryStream);
var
  hUpdate: THandle;
  bDiscard: BOOL;
begin
  hUpdate := BeginUpdateResource(PChar(FileName), True);
  Win32Check(hUpdate <> 0); // <-- ADD THIS!
  bDiscard := True;
  try
    Win32Check(UpdateResource(hUpdate, RT_RCDATA, 'ID', LANG_NEUTRAL, Inputstream.Memory, Inputstream.Size));
    bDiscard := False;
  finally
    EndUpdateResource(hUpdate, bDiscard);
  end;
end;

关于delphi - 在 Delphi 中创建和加载资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36140564/

相关文章:

c++ - std::vector 在重新分配时无论如何调用包含对象的析构函数?

delphi - 在 Delphi 版本 <= 2007 中处理 Unicode 字符串

delphi - 无法访问的字段错误

mysql - 使用 TIdHTTPServer 时如何防止 "MySql has gone away"

string - 如何使用Delphi和writebinary命令将二进制值的字符串格式写入注册表?

multithreading - 在线程内部时括号不释放资源

delphi - 重新安装Windows而不重新注册Delphi

javascript - 在Webworker中使用AJAX加载javascript资源

java - 如何将类设置为始终在其自己的项目文件夹中搜索给定路径?

java - 在 Java 中使用资源文件