在 Delphi 中创建和加载资源 [英] Create and load resources in Delphi

查看:52
本文介绍了在 Delphi 中创建和加载资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序,当一个按钮被加载时,它会在应用程序本身中手动创建一个资源(在这种情况下是一个图像),然后读取资源以显示在 timage.El 问题是它似乎创建了资源很好,但是当我要加载资源时,它说在您查找时找不到它.

Hi I have a program that when a button is loaded, creates a resource manually in the application itself (in this case an image) and then reads the resource to display in a timage.El problem is that it seems that creates the resource well but when I want load the resource says it can not find it when you are looking for.

代码.

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() 当您需要更新其资源时.

In general, a running process cannot update its own resources, as its executable file is locked and not writable. To do what you are attempting, you should move the resource to a separate DLL, then you can load the DLL dynamically via LoadLibrary() when you need to load its resources, and unload it via FreeLibrary() when you need to update its resources.

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() 的返回值以确保它确实成功.

Also, you are not checking the return value of BeginUpdateResource() to make sure it is actually successful before then calling 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;

这篇关于在 Delphi 中创建和加载资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆