学习资源数量

Gu.*_*u. 2 delphi

Delphi 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));
Run Code Online (Sandbox Code Playgroud)

问题:如何在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;
Run Code Online (Sandbox Code Playgroud)

但由于某种原因,它会导致错误(甚至设计尝试 - 除了没有帮助),当i: = 4201:(当i=0..4200>4210,一切都好.

RRU*_*RUZ 8

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

检查这个样本.

{$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.
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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

Min:=(Id - 1) * 16;
Max:=(Id * 16) - 1;
Run Code Online (Sandbox Code Playgroud)

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