【问题标题】:To learn numbers of resources学习资源数量
【发布时间】:2011-09-23 21:40:51
【问题描述】:

德尔福 Xe,Win7x64

请求已知编号的字符串资源:

Function GuGetStrRes(Fn:string;Nom:integer):string;
var 
  h:THandle;
  buffer:array [0..255] of Char;
begin
  Result:='';
  if fileexists(Fn)=false then 
    exit;
  Try
    h:=LoadLibraryEx(pchar(Fn),0,LOAD_LIBRARY_AS_DATAFILE);
    if h=0 then 
      exit;
    if LoadString(h, Nom, buffer, SizeOf(buffer)) > 0 then 
      Result:=string(buffer);
    FreeLibrary(h);
  Except
    Try 
      if h<>0 then 
        FreeLibrary(h);
    except 

    end;
  End;
End;

// Use
Showmessage(GuGetStrRes('c:\windows\system32\shell32.dll',4200));

问题:如何在 DLL 中学习所有数量的“字符串”资源?比如接收一个数组:11,22,23,24,40000等等(不能一个接一个)

试过了:

...
var 
  dllname, str:string;
begin
  dllname: ='c:\windows\system32\shell32.dll'; 
  str: = ";
  For i: = 0 to 10000 do 
  begin
    str: = GuGetStrRes (dllname, i);
    if str <> " then 
      memo1.lines.add (inttostr (i) + ' - ' +str);
  end;
end;

但由于某种原因,当i: = 4201 :( 当i=0..4200 和&gt;4210 时,一切正常。

【问题讨论】:

  • “它会导致错误”在不知道确切错误和错误消息的内容的情况下意味着什么。请编辑您的帖子并提供该信息;如果有的话,我们可以更轻松(更快)地提供帮助。
  • 如果那是您尝试过的代码,那么它不起作用也就不足为奇了。它甚至没有编译!
  • "如果 fileexists(Fn)=false then",真的吗?
  • 旁白。不要使用 try/except 来管理生命周期。使用 try/finally。

标签: delphi


【解决方案1】:

要枚举资源字符串,您必须使用传递RT_STRING 类型的EnumResourceNames 函数。

检查此示例。

{$APPTYPE CONSOLE}

uses
  Classes,
  Windows,
  SysUtils;

function EnumResNameProc(hModule : THandle; lpszType, lpszName : PChar; lParam : longint) : boolean; stdcall;
var
  Id       : LongInt;
  Min      : Integer;
  Max      : Integer;
  Index    : Integer;
  Buffer   : PWChar;
  Stream   : TResourceStream;
  Len      : Word;
begin
 if Longint(lpszName)<65535 then
 begin
    Id:= longint(lpszName);
    Writeln(Format('RT_STRING ID %d',[Id]));
    Min:=(Id - 1) * 16;
    Max:=(Id * 16) - 1;
    Stream:=TResourceStream.CreateFromID(hModule,Id,RT_STRING);
    try
        Buffer:=Stream.Memory;
        for Index:=Min to Max do
        begin
           //determine the length of the string
           Len:=Word(Buffer^);
           if Len>0 then
           begin
             Writeln(Format('  String ID %d',[Index]));
             Inc(Buffer,Len+1);
           end
           else
             Inc(Buffer);
        end;
    finally
       Stream.Free;
    end;
 end
 else
    Writeln(string(lpszName));
  Result := true;
end;


procedure  EnumerateStringResources(const FileName:string);
var
  hModule : Thandle;
  restype : byte;
begin
  hModule := LoadLibraryEx(PChar(FileName), 0, LOAD_LIBRARY_AS_DATAFILE);
  if hModule=0 then exit
  else
  try
     EnumResourceNames(hModule, RT_STRING, @EnumResNameProc, 0);
  finally
     FreeLibrary(hModule);
  end;
end;


begin
  try
    EnumerateStringResources('YourApplication.exe');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  readln;
end.

并且取决于您的资源的输出将是这样的

RT_STRING ID 4080
  String ID 65264
  String ID 65265
  String ID 65266
  String ID 65267
  String ID 65268
  String ID 65269
  String ID 65270
  String ID 65271
  String ID 65272
  String ID 65273
  String ID 65274
  String ID 65275
  String ID 65276
  String ID 65277
  String ID 65278
  String ID 65279
RT_STRING ID 4081
  String ID 65280
  String ID 65281
  String ID 65282
  String ID 65283
  String ID 65284
  String ID 65285
  String ID 65286
  String ID 65287
  String ID 65288
  String ID 65289
  String ID 65290
  String ID 65291
  String ID 65292
  String ID 65293
  String ID 65294
  String ID 65295

更新 我更新了答案以反映字符串表中的字符串 id,字符串以 16 个为一组组合在一起。所以第一个包包含字符串 0 到 15,第二个包包含字符串 16 到 31,依此类推。所以计算字符串id的公式可以这样确定

Min:=(Id - 1) * 16;
Max:=(Id * 16) - 1;

有关更多信息,您可以阅读 Raymond Chen The format of string resources 的这篇文章

【讨论】:

  • 感谢您的想法,仍然在这里提供帮助:blog.onkeysoft.com/tag/enumresnameproc
  • @NGLN,是的,当需要False 时,可能会返回意外的TRUE(布尔值永远不会扩展为 LongBool)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-30
  • 2011-07-02
  • 2011-07-18
  • 2010-10-04
  • 1970-01-01
相关资源
最近更新 更多