在Delphi中列出名称和类型的资源

FF2

我正在尝试使用资源名称和资源类型为“ RT_BITMAP”或任何其他名称列出程序的所有资源。

代码 :

var
  Form1: TForm1;
  list_resources: string;

function EnumResNameProc(lpszName: PChar; lParam: integer; lpszType: PChar;
  hModule: Cardinal): BOOL;
begin
  list_resources := list_resources + sLineBreak + lpszName + ' - ' + lpszType;
  Result := True;
end;

procedure TForm1.btnListResourcesClick(Sender: TObject);
begin
  EnumResourceNames(0, RT_RCDATA, @EnumResNameProc, 0);
  Memo1.Lines.Add(list_resources);
end;

代码运行良好,但是从不显示资源类型,这是什么问题?

戴维·赫弗南

您的代码的第一个问题是回调函数具有错误的调用约定和确实错误的签名。应该这样声明:

function EnumResNameProc(hModule: HMODULE; lpszType, lpszName: PChar; 
  lParam: LONG_PTR): BOOL; stdcall;

您的代码产生的输出完全是偶然的。正确获得这些功能的签名非常重要。我不知道您的签名来自哪里。看起来您刚刚做好了!MSDN上的文档具有正确的签名。Embarcadero通过声明接受回调的API函数(这意味着忽略对签名的类型检查)来使事情变得困难。因此,责任就落在了你身上。请非常仔细地阅读文档。

解决此问题后,还有更多工作要做。资源类型以及实际上的资源名称可以是整数或字符串。习惯上,将<65536的值解释为整数,否则,该值是指向以null终止的字符数组的指针。您可以调用Is_IntResourceWindows宏的Delphi转换,而不是硬编码该魔术常数IS_INTRESOURCE

在您的情况下,您将接收命名资源,但是资源类型实际上是整数值。在Windows单元中:

const
  RT_CURSOR       = MakeIntResource(1);
  RT_BITMAP       = MakeIntResource(2);
  RT_ICON         = MakeIntResource(3);
  RT_MENU         = MakeIntResource(4);
  RT_DIALOG       = MakeIntResource(5);
  RT_STRING       = MakeIntResource(6);
  RT_FONTDIR      = MakeIntResource(7);
  RT_FONT         = MakeIntResource(8);
  RT_ACCELERATOR  = MakeIntResource(9);
  RT_RCDATA       = System.Types.RT_RCDATA; //MakeIntResource(10);
  DIFFERENCE = 11;
  RT_GROUP_CURSOR = MakeIntResource(DWORD(RT_CURSOR) + DIFFERENCE);
  RT_GROUP_ICON   = MakeIntResource(DWORD(RT_ICON) + DIFFERENCE);
  RT_VERSION      = MakeIntResource(16);
  RT_DLGINCLUDE   = MakeIntResource(17);
  RT_PLUGPLAY     = MakeIntResource(19);
  RT_VXD          = MakeIntResource(20);
  RT_ANICURSOR    = MakeIntResource(21);
  RT_ANIICON      = MakeIntResource(22);
  RT_HTML         = MakeIntResource(23);
  RT_MANIFEST     = MakeIntResource(24);

另一个惯例是,您使用#符号来表示数字标识符。因此,您可以采用以下策略:

  • 如果Is_IntResource返回True,则将数值转换为字符串并以前缀#
  • 否则,将其视为指向以null终止的字符数组的指针。

代码很简单:

function ResourceNameToString(lpszName: PChar): string;
begin
  if Is_IntResource(lpszName) then
    Result := '#' + IntToStr(NativeUInt(lpszName))
  else
    Result := lpszName;
end;

必须对名称和类型执行此操作。否则,当您的代码尝试取消对实际上表示整数的指针的引用时,您的代码将因运行时访问冲突错误而失败。如果您修复了回调签名,但没有进行进一步更改,则问题中的代码将以这种方式失败。

如果希望您的代码更有帮助,您将检测预定义的资源类型并给予特殊对待。

function ResourceTypeToString(lpszType: PChar): string;
begin
  case NativeUInt(lpszType) of
  NativeUInt(RT_CURSOR):
    Result := 'RT_CURSOR';
  NativeUInt(RT_BITMAP):
    Result := 'RT_BITMAP';
  NativeUInt(RT_RCDATA):
    Result := 'RT_RCDATA';
  // etc.
  else
    Result := ResourceNameToString(lpszType);
  end;
end;

我让您填写缺失的值。

像这样将它们放在一起:

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows;

function ResourceNameToString(lpszName: PChar): string;
begin
  if Is_IntResource(lpszName) then
    Result := '#' + IntToStr(NativeUInt(lpszName))
  else
    Result := lpszName;
end;

function ResourceTypeToString(lpszType: PChar): string;
begin
  case NativeUInt(lpszType) of
  NativeUInt(RT_CURSOR):
    Result := 'RT_CURSOR';
  NativeUInt(RT_BITMAP):
    Result := 'RT_BITMAP';
  NativeUInt(RT_RCDATA):
    Result := 'RT_RCDATA';
  // etc.
  else
    Result := ResourceNameToString(lpszType);
  end;
end;

function EnumResNameProc(hModule: HMODULE; lpszType, lpszName: PChar; 
  lParam: LONG_PTR): BOOL; stdcall;
begin
  Writeln(ResourceTypeToString(lpszType) + ' - ' + ResourceNameToString(lpszName));
  Result := True;
end;

begin
  EnumResourceNames(0, RT_RCDATA, @EnumResNameProc, 0);
  Readln;
end.

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

列出名称和出现次数

来自分类Dev

列出名称中仅包含数字的文件

来自分类Dev

Django-mptt没有在模板中列出名称

来自分类Dev

如何使用AWS CLI在同一行中列出名称,状态,实例大小和AZ的所有实例

来自分类Dev

列出名称并随机配对(SQL)

来自分类Dev

列出名称中带有“ SALARIO”字样的目录中以“ .txt”结尾的文件,而不使用管道

来自分类Dev

使用reg exp查找并列出名称中包含数字的文件

来自分类Dev

在没有NetworkManager的Ubuntu 14.04中列出名称服务器

来自分类Dev

如何打开或列出名称与Bash中的两种模式匹配的所有文件

来自分类Dev

从SQL表中的组合框中列出名字和姓氏

来自分类Dev

列出名称作为 JSON 对象名称

来自分类Dev

是否可以在派生Generic的记录数据类型中列出字段的名称和类型?

来自分类Dev

MySQL查询以列出名称以相同字符开头和结尾的所有员工(区分大小写)

来自分类Dev

Excel如何创建引用并列出名称?

来自分类Dev

如何使用psql列出名称不包含数字的表?

来自分类Dev

如何使用 vba 列出名称范围内的值?

来自分类Dev

如何在启用延迟扩展的情况下在dos批处理中列出名称包含感叹号的文件?

来自分类Dev

如何在启用延迟扩展的情况下在dos批处理中列出名称包含感叹号的文件?

来自分类Dev

RegExp:从javascript中的字符串中找出名称和状态

来自分类Dev

phpstorm,windows和subversion。检出名称中带有:的文件

来自分类Dev

phpstorm,windows和subversion。检出名称中带有:的文件

来自分类Dev

如何从一个表中列出ID列,然后基于那些ID LINQ从另一个列中列出名称?

来自分类Dev

列出 r 中的名称和值

来自分类Dev

如何在Google Cloud Platform(GCP)中跨服务(API),资源类型和项目列出,查找或搜索IAM策略?

来自分类Dev

C ++中的名称和类型

来自分类Dev

在pulumi中,如何获得完全限定的资源类型名称?

来自分类Dev

无法通过列出名称的文本文件安装软件包

来自分类Dev

列出名称长度在3到6个字符之间的所有文件

来自分类Dev

是否可以列出名称上至少包含3个字母的所有文件?

Related 相关文章

  1. 1

    列出名称和出现次数

  2. 2

    列出名称中仅包含数字的文件

  3. 3

    Django-mptt没有在模板中列出名称

  4. 4

    如何使用AWS CLI在同一行中列出名称,状态,实例大小和AZ的所有实例

  5. 5

    列出名称并随机配对(SQL)

  6. 6

    列出名称中带有“ SALARIO”字样的目录中以“ .txt”结尾的文件,而不使用管道

  7. 7

    使用reg exp查找并列出名称中包含数字的文件

  8. 8

    在没有NetworkManager的Ubuntu 14.04中列出名称服务器

  9. 9

    如何打开或列出名称与Bash中的两种模式匹配的所有文件

  10. 10

    从SQL表中的组合框中列出名字和姓氏

  11. 11

    列出名称作为 JSON 对象名称

  12. 12

    是否可以在派生Generic的记录数据类型中列出字段的名称和类型?

  13. 13

    MySQL查询以列出名称以相同字符开头和结尾的所有员工(区分大小写)

  14. 14

    Excel如何创建引用并列出名称?

  15. 15

    如何使用psql列出名称不包含数字的表?

  16. 16

    如何使用 vba 列出名称范围内的值?

  17. 17

    如何在启用延迟扩展的情况下在dos批处理中列出名称包含感叹号的文件?

  18. 18

    如何在启用延迟扩展的情况下在dos批处理中列出名称包含感叹号的文件?

  19. 19

    RegExp:从javascript中的字符串中找出名称和状态

  20. 20

    phpstorm,windows和subversion。检出名称中带有:的文件

  21. 21

    phpstorm,windows和subversion。检出名称中带有:的文件

  22. 22

    如何从一个表中列出ID列,然后基于那些ID LINQ从另一个列中列出名称?

  23. 23

    列出 r 中的名称和值

  24. 24

    如何在Google Cloud Platform(GCP)中跨服务(API),资源类型和项目列出,查找或搜索IAM策略?

  25. 25

    C ++中的名称和类型

  26. 26

    在pulumi中,如何获得完全限定的资源类型名称?

  27. 27

    无法通过列出名称的文本文件安装软件包

  28. 28

    列出名称长度在3到6个字符之间的所有文件

  29. 29

    是否可以列出名称上至少包含3个字母的所有文件?

热门标签

归档