Recent

Author Topic: SOLVED Free pascal resource file question. list resources of <type> in .res file  (Read 5395 times)

muller59

  • New Member
  • *
  • Posts: 16
using fpc 3.0.4 i create a program that uses data from a FPC resource file (.res).
i can read the individual resources like this fine

ResNam : string;
ResNam := 'RESOURCENAME';
S := TResourceStream.Create(HInstance, ResNam, RT_RCDATA);
F := TFileStream.Create(sPoPath_nl + '/' + sPoFile_nl, fmCreate);
F.CopyFrom(S, S.Size);

what i need is a function to read all resource names of type RT_RCDATA from the file. the documentation is not really clear about this (imho).

any hint will be appreciated
« Last Edit: August 29, 2020, 01:57:50 pm by muller59 »
--
Regards,
Rob.
----------
lubuntu 20.04, Lazarus trunk, FPC 3.0.4
Raspbian Buster, Lazarus trunk, FPC 3.0.4

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Use a TResources object (unit resource of package fcl-res): load it with LoadFromFile() or LoadFromStream() and traverse its Items[].

That's the basic way to do it.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

dsiders

  • Hero Member
  • *****
  • Posts: 1052
Use a TResources object (unit resource of package fcl-res): load it with LoadFromFile() or LoadFromStream() and traverse its Items[].

That's the basic way to do it.

There are some relevant code samples in fclres.chm too.
Preview Lazarus 3.99 documentation at: https://dsiders.gitlab.io/lazdocsnext

muller59

  • New Member
  • *
  • Posts: 16
Thanks Friends, i will look into that.
Much appreciated.
--
Regards,
Rob.
----------
lubuntu 20.04, Lazarus trunk, FPC 3.0.4
Raspbian Buster, Lazarus trunk, FPC 3.0.4

muller59

  • New Member
  • *
  • Posts: 16
@ lucamar
i tried and failed.

i did

Code: Pascal  [Select][+][-]
  1. program reslist;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   Classes, SysUtils, resource,
  7. // You need to specify which resources you want to be able to read.
  8. // The units initialize themselves and register themselves as readers....
  9.   resreader;
  10.  
  11. var
  12.   resources : TResources;
  13.   reader : TAbstractResourceReader;
  14.   inFile : TFileStream;
  15.   i : integer;
  16.  
  17. {$R *.res}
  18.  
  19. begin
  20.   resources:=TResources.Create;
  21.   inFile:=TFileStream.Create(paramstr(1), fmOpenRead );
  22.   // Use FindReader to let TResources find the appropriate reader for the file
  23.   reader:=TResources.FindReader(inFile);
  24.   writeln('Selected reader: ',reader.Description);
  25.   resources.LoadFromStream(inFile,reader);
  26.  
  27.   for i:=0 to resources.Count-1 do
  28.   begin
  29.     //resread := Tabtractresourcereader.create
  30.     writeln(inttostr(i));
  31.     writeln(resources.getname(resources.Items[i]));  <<< source of error
  32.   end;
  33.  
  34.   resources.Free;
  35.   reader.Free;
  36.   inFile.Free;
  37. end.
 

compilation error: reslist.lpr(31,20) Error: identifier idents no member "getname" 

given this program, i can see there are 9 resources in the resource file if i comment out the error line, but i cannot get to the names.
i trawled thought the resources source of fpc, but i get lost in the class attribute types...
can anyone help me get the correct code to print the resource names.
i have attached the test resource list as well.

as always, thanks in advance for your help
« Last Edit: August 17, 2020, 02:14:15 pm by muller59 »
--
Regards,
Rob.
----------
lubuntu 20.04, Lazarus trunk, FPC 3.0.4
Raspbian Buster, Lazarus trunk, FPC 3.0.4

lucamar

  • Hero Member
  • *****
  • Posts: 4219
AFAICT TResources has no method called GetName. Try with this (untested, might or might not work):

Code: Pascal  [Select][+][-]
  1. program reslist;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   Classes, SysUtils, resource,
  7. // You need to specify which resources you want to be able to read.
  8. // The units initialize themselves and register themselves as readers....
  9.   resreader;
  10.  
  11. var
  12.   resources : TResources;
  13.   reader : TAbstractResourceReader;
  14.   inFile : TFileStream;
  15.   i : integer;
  16.  
  17. {$R *.res}
  18.  
  19. begin
  20.   resources:=TResources.Create;
  21.   inFile:=TFileStream.Create(paramstr(1), fmOpenRead );
  22.   // Use FindReader to let TResources find the appropriate reader for the file
  23.   reader:=TResources.FindReader(inFile);
  24.   writeln('Selected reader: ',reader.Description);
  25.   resources.LoadFromStream(inFile,reader);
  26.  
  27.   for i:=0 to resources.Count-1 do
  28.   begin
  29.     //resread := Tabtractresourcereader.create
  30.     writeln(inttostr(i));
  31.     writeln(resources.Items[i].Name);
  32.   end;
  33.  
  34.   resources.Free;
  35.   reader.Free;
  36.   inFile.Free;
  37. end.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

muller59

  • New Member
  • *
  • Posts: 16
Never mind, found an answer

resources.Name.Name does the trick, a bit counter-intuitive IMHO
--
Regards,
Rob.
----------
lubuntu 20.04, Lazarus trunk, FPC 3.0.4
Raspbian Buster, Lazarus trunk, FPC 3.0.4

TRon

  • Hero Member
  • *****
  • Posts: 2435
resources.Name.Name does the trick, a bit counter-intuitive IMHO
Yes and no  :D

afaik there are two type of resources as in those that are identified by their name and those that are identified by ID. That is probably why it was implemented the way it is. The counter-intuitive part as far as I am concerned stems from both properties name and _type pointing to class TResourceDesc. That is unless there exists resources that actually can be identified (as in: stored) in both ways.

BTW: You both seem to load the loader manually while I was lazy and included all the individual reader units so I wouldn't have to. No idea what should be the way to actually use it though, or if that even matters.

Edit: my bad. the type property is the resource listing while name property for the actual resource. It is always using either ID or name as indicated by the DescType (sub)property.
Code: [Select]
Found 96 resources in file /home/tron/projects/bunch_of_resources
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 1
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 2
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 3
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 4
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 5
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 6
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 7
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 8
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 9
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 10
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 11
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 12
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 13
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 14
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 15
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 16
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 17
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 18
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 19
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 20
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 21
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 22
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 23
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 24
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 25
res.Type.ID   =   1 (RT_CURSOR), res.Name.ID   = 26
res.Type.ID   =   3 (RT_ICON), res.Name.ID   = 1
res.Type.ID   =   3 (RT_ICON), res.Name.ID   = 2
res.Type.ID   =   3 (RT_ICON), res.Name.ID   = 3
res.Type.ID   =   3 (RT_ICON), res.Name.ID   = 4
res.Type.ID   =   3 (RT_ICON), res.Name.ID   = 5
res.Type.ID   =   3 (RT_ICON), res.Name.ID   = 6
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_ABORT
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_ABORT_150
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_ABORT_200
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_ALL
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_ALL_150
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_ALL_200
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_ARROWRIGHT
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_ARROWRIGHT_150
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_ARROWRIGHT_200
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_CANCEL
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_CANCEL_150
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_CANCEL_200
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_CLOSE
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_CLOSE_150
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_CLOSE_200
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_HELP
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_HELP_150
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_HELP_200
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_IGNORE
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_IGNORE_150
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_IGNORE_200
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_NO
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_NO_150
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_NO_200
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_OK
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_OK_150
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_OK_200
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_RETRY
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_RETRY_150
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_RETRY_200
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_YES
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_YES_150
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = BTN_YES_200
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = DIALOG_CONFIRMATION
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = DIALOG_ERROR
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = DIALOG_INFORMATION
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = DIALOG_SHIELD
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = DIALOG_WARNING
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = SORTASC
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = SORTASC_150
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = SORTASC_200
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = SORTASC_50
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = SORTASC_75
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = SORTDESC
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = SORTDESC_150
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = SORTDESC_200
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = SORTDESC_50
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = SORTDESC_75
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = TFRMCLOCKS
res.Type.ID   =  10 (RT_RCDATA), res.Name.Name = TFRMMAIN
res.Type.ID   =  12 (RT_GROUP_CURSOR), res.Name.Name = CUR_1
res.Type.ID   =  12 (RT_GROUP_CURSOR), res.Name.Name = CUR_10
res.Type.ID   =  12 (RT_GROUP_CURSOR), res.Name.Name = CUR_12
res.Type.ID   =  12 (RT_GROUP_CURSOR), res.Name.Name = CUR_13
res.Type.ID   =  12 (RT_GROUP_CURSOR), res.Name.Name = CUR_14
res.Type.ID   =  12 (RT_GROUP_CURSOR), res.Name.Name = CUR_15
res.Type.ID   =  12 (RT_GROUP_CURSOR), res.Name.Name = CUR_16
res.Type.ID   =  12 (RT_GROUP_CURSOR), res.Name.Name = CUR_17
res.Type.ID   =  12 (RT_GROUP_CURSOR), res.Name.Name = CUR_18
res.Type.ID   =  12 (RT_GROUP_CURSOR), res.Name.Name = CUR_20
res.Type.ID   =  12 (RT_GROUP_CURSOR), res.Name.Name = CUR_21
res.Type.ID   =  12 (RT_GROUP_CURSOR), res.Name.Name = CUR_22
res.Type.ID   =  14 (RT_GROUP_ICON), res.Name.Name = MAINICON
res.Type.ID   =  24 (RT_MANIFEST), res.Name.ID   = 1
« Last Edit: August 17, 2020, 05:59:34 pm by TRon »

 

TinyPortal © 2005-2018