在Delphi中创建和加载资源

时间:2016-03-21 20:06:44

标签: 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;

我解决了这个问题?

1 个答案:

答案 0 :(得分:4)

通常,正在运行的进程无法更新自己的资源,因为其可执行文件已锁定且无法写入。要执行您尝试的操作,您应该将资源移动到单独的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;

另外,在调用BeginUpdateResource()之前,您没有检查UpdateResource()的返回值以确保其实际成功。

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;