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,一切都好.
要枚举资源字符串,必须使用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