【问题标题】:Delphi: Loop data in resource fileDelphi:资源文件中的循环数据
【发布时间】:2012-11-21 10:39:48
【问题描述】:

我需要在资源文件中循环并使用以下语句加载所有 BMP 文件; bBitmap.Handle := LoadBitmap(hInstance, 'IMAGE_NAME');

如何循环资源文件;我是否必须进行常规 IO 操作并将其视为文本文件?我可以读取每一行并创建一个位图名称列表,而不是在单独的循环中执行上述语句来加载位图。或者 Delphi 库中是否有内置方法来执行此操作?

FILE_NAME_1 位图“btnFile1.bmp”
FILE_NAME_2 位图“btnFile2.bmp”
....

【问题讨论】:

  • 资源是可执行文件内资源部分中的二进制块。一旦构建了可执行文件,就没有“资源文件”,而且它绝对不是文本格式。 “资源文件”是一个预编译的二进制文件,它在创建时链接到可执行文件;资源文件是从文本“资源脚本”中的源代码创建的(除非它是由 IDE 预先创建为二进制文件)。
  • 好吧,您可以破解它,以便将 .RC 文件作为常量值包含在您的应用程序代码中。然后,您的应用程序可以解析常量,检索所有图像名称并加载它们。像const RC_CONTENTS = '''' {$INCLUDE MYRCFILE.RC} ''''; 之类的东西你可能不得不重命名 .rc 才能使它工作(或者 res 将被包含两次),你可能会发现如果可能的话,获得正确的引号会很麻烦。跨度>
  • 谢谢。我看到我必须预先定义值并使用它们。我将尝试按照 Marjan 的建议将这些值包含为常量。在最坏的情况下,我可能会创建一个字符串数组。不过图片列表很长。
  • XNResource Editior 是 AFAIK 开源 delphi。所以它可以列出资源,你可能会在那里找到一些东西。
  • 您可以使用 WinAPI 函数 EnumResourceNames,我怀疑 XNResource Editor 使用它来列出它们(正如 @bummi 提到的)。我没有方便的 Delphi 示例,但是快速的 SO/MSDN 搜索也没有找到。

标签: delphi embedded-resource resource-file


【解决方案1】:

我建议您看一下 Delphi 安装中包含的资源浏览器演示。您可以在“c:\Users\Public\Documents\RAD Studio\9.0\Samples\Delphi\VCL\resXplor\resxplor.dpr”中找到它(针对不同的路径/Delphi 版本进行调整)。 在 ExeImage.pas 文件中有一些类可以让您轻松地将资源分配给 TPicture 等。

【讨论】:

  • 这肯定是相关的,示例应用从 exe 加载资源名称。我浏览了代码,但不想通过那里的所有内容来找出我需要的东西。我刚刚搜索了关键字 EnumResourceNames 来查找上面建议的信息。
【解决方案2】:

Ken White 建议的 EnumResourceNames 运行良好,而且实现起来非常简单。无法接受它作为答案,因为他只留下了评论。

这是我使用该建议的解决方案;

在我加载图像的过程中,我添加了以下代码行;

var
  returnVal:bool;
  hMdl: HMODULE;
begin
  hMdl:=LoadLibraryEX('FileNameWithResources.exe',0,LOAD_LIBRARY_AS_DATAFILE);
  // I load bitmaps so RT_BITMAP parameter is chosen
  returnVal:=EnumResourceNames(hMdl,RT_BITMAP,@Callback,0);

@callback 函数返回一个布尔值。你必须把它放在类级别,在类的实现代码之前。没有声明。我的类是单例的,所以我调用一个类级别的过程来将值添加到 TStringList。如果您有更复杂的 if 语句并且想要循环所有内容,请不要返回 false。如果您在任何时候返回 false,则对该函数的调用将结束,您将无法获得其余的资源名称。

function Callback(handle:THandle;ResType:PChar;ResName:Pchar;long:Lparam):bool;stdcall;
var
      tempString: string;    
begin  
      tempString := resname;
      if length(tempString) > 0 then begin
        MyClassName.AddToResourceNames(tempString);
        result := true;
      end else
        result := false;
end;

【讨论】:

  • 我们不应该也调用 FreeLibrary(hMdl);
  • 这适用于 RT_BITMAP 资源,但是当我尝试使用 RT_STRING 时,我在回调函数中遇到访问冲突。这是为什么呢?
猜你喜欢
  • 2010-11-23
  • 1970-01-01
  • 2011-10-17
  • 2012-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
相关资源
最近更新 更多