【问题标题】:Delphi Package Resources - EResNotFoundDelphi 软件包资源 - EResNotFound
【发布时间】:2017-02-22 19:49:03
【问题描述】:

已经在 Google 上搜索过解决方案,但没有任何建议对我有用,所以要么我遗漏了什么,要么我做错了什么。

我的 Delphi XE2 应用程序中有许多包,其中一些包包含最终是 PNG 图像的 RCDATA 资源。

使用资源的控件在 Delphi XE2 设计器中工作得非常好——资源按预期加载和绘制。当我开始运行使用包/控件的主应用程序时,当控件尝试加载资源项时,我会看到一个 EResNotFound 异常:

handle := FindClassHInstance(Self.ClassType);
fPlaneImage := TPngImage.Create;
fPlaneImage.LoadFromResourceName(handle, 'IDC_IMG_PLANE');

当应用程序运行时,我收到以下错误:

Project PinPoint.exe 引发异常类 EResNotFound,并带有消息 IDC_IMG_PLANE not found'。

如果我在调试器中点击continue,我会得到:

Project PinPoint.exe 引发异常类 EPNGCouldNotLoadResource 并显示消息“无法从资源 ID 加载 png 图像。”。

我已尝试将句柄的所有变体传递给 LoadFromResource 函数:

fPlaneImage.LoadFromResourceName(HInstance, 'IDC_IMG_PLANE');
fPlaneImage.LoadFromResourceName(GetModuleHandle('AppCore.bpl'), 'IDC_IMG_PLANE');
fPlaneImage.LoadFromResourceName(FindClassHInstance(Self.ClassType), 'IDC_IMG_PLANE');

但它们都产生相同的异常。

我正在考虑是否更容易创建一个包含所有资源的独立包,然后从项目中的每个其他包中引用它,而不是每个包都有自己的资源,但我不确定这是否真的有效。

请任何人提供任何建议。

【问题讨论】:

  • 错误信息很清楚了吧?
  • @DavidHeffernan,好吧,除非资源存在,否则我会假设如此。
  • 系统告诉您没有具有该 ID 的资源。相信它。做一些调试来找出原因。一个明显的解释是在运行时加载了一个过时的包。
  • @weblar83:您是否将PNG 资源放入包的主.res 文件中?如果是这样,不要。该文件由 IDE 管理,它可以(并且可能会)清除自定义资源。它们应该在自己的 .res 文件中,该文件链接到包中。最简单的方法是编写一个引用PNG文件的.rc文件,例如(myres.rc):IDC_IMG_PLANE RCDATA myimage.png,然后使用{$R}指令链接包代码中的.rc文件,例如:{$R myres.res myres.rc}.
  • @weblar83:坏主意。没有理由将资源放入单独的包中。只要您将它们与每个包的主要资源分开,并正确链接它们,它们就可以在组件包中正常工作。您应该将每个组件的资源与组件本身保存在同一个包中,以允许FindClassHInstance() 工作。创建一个单独的资源包只是更多的工作,并且可能需要更多的部署。

标签: delphi resources


【解决方案1】:

尝试使用下面的FindResModule函数获取资源模块。

// use fPlaneImage.LoadFromResourceName(FindResModule('IDC_IMG_PLANE'), 'IDC_IMG_PLANE');

function FindResModule(const AResourceName: string): HINST;
var
  LModule: PLibModule;
begin
  LModule := LibModuleList;
  while Assigned(LModule) do
  begin
    Result := LModule.Instance;
    if (Result <> 0) and (FindResource(Result, PChar(AResourceName), RT_RCDATA) <> 0) then
      Exit;

    LModule := LModule^.Next;
  end;

  Result := 0;
end;

万一失败,资源很可能会“被链接器消除”。例如,当您创建自己的包并且您错过将带有资源的单元添加到您的包或应用程序文件时,可能会发生这种情况。只需将单位添加到应用程序的使用子句中即可。

如果您为资源创建一个单独的包,我认为没有什么坏处。它应该可以正常工作,但实际上并不是必需的。一点小提示,不需要BPL包,你可以把你的资源打包成DLL

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-23
    • 2018-02-19
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    • 2011-06-21
    相关资源
    最近更新 更多