Recent

Author Topic: Iterate Resourcestrings at runtime  (Read 918 times)

RoCkA

  • New member
  • *
  • Posts: 8
Iterate Resourcestrings at runtime
« on: February 19, 2026, 06:46:56 am »
Hi,
need help with this subject.

Problem:
At runtime i want to iterate through the available resourcestrings in my project and return the Value of any found resource name.
Tried with LoadResource.Find('xxx', 'RT_STRING') but only returned Nil.

Any help is very appreciated!
Thanks in advance :-*

Zvoni

  • Hero Member
  • *****
  • Posts: 3294
Re: Iterate Resourcestrings at runtime
« Reply #1 on: February 19, 2026, 08:21:32 am »
Keep a constant (global) array with the Names of the Ressources
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

RoCkA

  • New member
  • *
  • Posts: 8
Re: Iterate Resourcestrings at runtime
« Reply #2 on: February 19, 2026, 08:51:32 am »
Keep a constant (global) array with the Names of the Ressources

Sorry, but i think there is a misunderstanding.
I am trying to access the constants defined as resourcestring at runtime.

LeP

  • Full Member
  • ***
  • Posts: 197
Re: Iterate Resourcestrings at runtime
« Reply #3 on: February 19, 2026, 09:39:21 am »
EDIT: I tried this but doesn't work with Lazarus ... :(


If you are in Windows you can use the API to scan all IDs and you will have as results all resource strings of EXE.
I use it in Delphi since long times:

Code: Pascal  [Select][+][-]
  1. var Ix: Integer;
  2.      LenBuf: Integer;
  3.      Buffer: array[0..1023] of Char;
  4. begin
  5.   for Ix := 1 to 65535 do
  6.     begin
  7.       LenBuf := LoadString(HInstance, Ix, Buffer, Length(Buffer));
  8.       if LenBuf > 0 then
  9.         Writeln(Format('Resource ID: %d = %s', [Ix, Buffer]));
  10.     end;
  11. end;
  12.  

« Last Edit: February 19, 2026, 10:06:45 am by LeP »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12692
  • FPC developer.
Re: Iterate Resourcestrings at runtime
« Reply #4 on: February 19, 2026, 10:22:31 am »
Probably resourcestrings are not windows compatible, as Lazarus uses gettext derivatives for translations. Probably because it predates proper windows resource support.

If I take e.g. Anders Melander's  resource editor, and I run it on a lazarus binary I don't see the "stringtable" with resource strings that i see with Delphi binaries.

I also get warnings for its fileinfo record (malformed string record) and some unknown picture format warnings.

Short term, the smartest way would be to step through Lazarus' translation support to see how it accesses the strings.

See also bottom of  https://wiki.freepascal.org/Using_resourcestrings about rstconv c.s.
« Last Edit: February 19, 2026, 12:30:42 pm by marcov »

RoCkA

  • New member
  • *
  • Posts: 8
Re: Iterate Resourcestrings at runtime
« Reply #5 on: February 19, 2026, 07:09:23 pm »
Probably resourcestrings are not windows compatible, as Lazarus uses gettext derivatives for translations. Probably because it predates proper windows resource support.

If I take e.g. Anders Melander's  resource editor, and I run it on a lazarus binary I don't see the "stringtable" with resource strings that i see with Delphi binaries.

I also get warnings for its fileinfo record (malformed string record) and some unknown picture format warnings.

Short term, the smartest way would be to step through Lazarus' translation support to see how it accesses the strings.

See also bottom of  https://wiki.freepascal.org/Using_resourcestrings about rstconv c.s.
Yeah, thought the same. I will try to step through Lazarus translation unit.
Thanks

p.s. if i come with a handy solution, i will post it here

RoCkA

  • New member
  • *
  • Posts: 8
Re: Iterate Resourcestrings at runtime
« Reply #6 on: February 19, 2026, 07:11:17 pm »
EDIT: I tried this but doesn't work with Lazarus ... :(


If you are in Windows you can use the API to scan all IDs and you will have as results all resource strings of EXE.
I use it in Delphi since long times:

Code: Pascal  [Select][+][-]
  1. var Ix: Integer;
  2.      LenBuf: Integer;
  3.      Buffer: array[0..1023] of Char;
  4. begin
  5.   for Ix := 1 to 65535 do
  6.     begin
  7.       LenBuf := LoadString(HInstance, Ix, Buffer, Length(Buffer));
  8.       if LenBuf > 0 then
  9.         Writeln(Format('Resource ID: %d = %s', [Ix, Buffer]));
  10.     end;
  11. end;
  12.  

Thanks anyway for your effort. I really thought this was more straightforward solution, but a little tricky atm.

PascalDragon

  • Hero Member
  • *****
  • Posts: 6344
  • Compiler Developer
Re: Iterate Resourcestrings at runtime
« Reply #7 on: February 19, 2026, 08:32:52 pm »
Yeah, thought the same. I will try to step through Lazarus translation unit.

The resourcestring handling is implemented in unit ObjPas. Main interest for you would be SetResourceStrings function which gets passed an iterator function. By simply returning the passed in Value argument in the iterator (thus not changing anything) you essentially receive all resourcestrings.

RoCkA

  • New member
  • *
  • Posts: 8
Re: Iterate Resourcestrings at runtime
« Reply #8 on: February 20, 2026, 08:23:04 am »
Yeah, thought the same. I will try to step through Lazarus translation unit.

The resourcestring handling is implemented in unit ObjPas. Main interest for you would be SetResourceStrings function which gets passed an iterator function. By simply returning the passed in Value argument in the iterator (thus not changing anything) you essentially receive all resourcestrings.

Thank you, this did the trick and it works nice:

Code: Pascal  [Select][+][-]
  1. unit resources.lang;
  2.  
  3. {$mode ObjFPC}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils;
  9.  
  10. function FFindResStr(AString: String): String;
  11. function _FIterate(Name,Value : AnsiString; Hash : Longint; arg:pointer) : AnsiString;
  12. procedure SetResourceTable;
  13.  
  14. var _ResIDs: TStringList;
  15.  
  16. implementation
  17.  
  18. function _FIterate(Name,Value : AnsiString; Hash : Longint; arg:pointer) : AnsiString;
  19. var ss: TStringArray;
  20. begin
  21.   //Name comes with unit prefix unitname.resourcestringname
  22.   Result:= Value;
  23.   ss:= Name.Split(['.']);
  24.   if Length(ss) > 1 then
  25.    _ResIDs.AddPair(ss[High(ss)], Value)
  26.   else
  27.    _ResIDs.AddPair(Name, Value);
  28. end;
  29.  
  30. function FFindResStr(AString: String): String;
  31. begin
  32.   Result:= _ResIDs.Values[AString];
  33. end;
  34.  
  35. procedure SetResourceTable;
  36. begin
  37.   SetResourceStrings(@_FIterate, nil);
  38. end;
  39.  
  40. initialization
  41. begin
  42.  _ResIDs:= TStringList.Create;
  43.  SetResourceTable;
  44. end;
  45.  
  46. finalization
  47.  _ResIDs.Free;
  48.  
  49. end.
  50.  
  51.  

PascalDragon

  • Hero Member
  • *****
  • Posts: 6344
  • Compiler Developer
Re: Iterate Resourcestrings at runtime
« Reply #9 on: February 23, 2026, 09:34:18 pm »
Thank you, this did the trick and it works nice:

Sidenote: you don't need to declare your _FIterate as part of the interface-section for this to work.

 

TinyPortal © 2005-2018