Recent

Author Topic: How to enumerate all TObject types used in a project?  (Read 1153 times)

vfclists

  • Hero Member
  • *****
  • Posts: 1147
    • HowTos Considered Harmful?
How to enumerate all TObject types used in a project?
« on: February 03, 2024, 10:56:45 am »
For now I need it to mainly for two things:

1. To get the UnitName for every component used in an application in order to extend the LFM to PAS code at both design time and at runtime.

2. To fill out the object class names in order to load components from LFM files at runtime.

Code: Pascal  [Select][+][-]
  1. procedure TLayoutDesignerFormOne.OnFindClass(Reader: TReader;
  2.   const AClassName: string; var AComponentClass: TComponentClass);
  3. var
  4.   objClassName, msg: string;
  5.   E: Exception;
  6. begin
  7.   objClassName := UpperCase(AClassName);
  8.   case objClassName of
  9.     'TDBGRID': AComponentClass := TDBGrid;
  10.     'TATSYNEDIT': AComponentClass := TATSynEdit;
  11.     'TATSCROLLBAR': AComponentClass := TATScrollBar;
  12.   else
  13.     self.mmoMessages01.Lines.Add(AClassName + ' is not listed');
  14.     msg := (AClassName + ' : Type Unknown');
  15.     mmoMessages01.Lines.Add(msg);
  16.     E := Exception.Create(msg);
  17.     ShowException(E, ExceptAddr);
  18.  
  19.     E.Free;
  20.   end;
  21.  
  22. end;
  23.  
Lazarus 3.0/FPC 3.2.2

jamie

  • Hero Member
  • *****
  • Posts: 6811
Re: How to enumerate all TObject types used in a project?
« Reply #1 on: February 03, 2024, 03:47:39 pm »
I guess you should be scanning the folder of a compiled project for all the *.LFM files.

That would be my best guess.
 :(
The only true wisdom is knowing you know nothing

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: How to enumerate all TObject types used in a project?
« Reply #2 on: February 03, 2024, 03:58:16 pm »
For Delphi it's pretty easy, you just need to readout the .exe file :D

I try if I find in FPC compiled files something similar but I doubt it.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

jamie

  • Hero Member
  • *****
  • Posts: 6811
Re: How to enumerate all TObject types used in a project?
« Reply #3 on: February 03, 2024, 04:33:10 pm »
You can read the resource of a lazarus EXE file to obtain the LFM string.
The only true wisdom is knowing you know nothing

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10897
  • Debugger - SynEdit - and more
    • wiki
Re: How to enumerate all TObject types used in a project?
« Reply #4 on: February 03, 2024, 05:28:46 pm »
"All TObject"... => Including TStringList, TStream, ....
Or just components/controls?

And if the latter, only those that are part of the form (and in the lfm) or all other too?

E.g. if your form does not have any button on it, and does not have any field of type TButton... You can still do
Code: Pascal  [Select][+][-]
  1. procedure foo;
  2. var
  3.   b: TButton; //local variable
  4. begin
  5.   b:= TButton.Create(Form1);
  6.   b.parent := Form1;
  7. end;

Such local only used stuff, will be hard to find.

Equally hard, any field on the form that is not published.




Also
Code: Pascal  [Select][+][-]
  1. TForm1 = class(TForm)
  2. FLabeledEdit: TLabeledEdit;
There will be a TEdit on the form, but there is no field of type TEdit.

And you can of course have lfm and form out of sync (though likely that gives error at runtime). In that case too, classes may be used, that aren't found via the form.



For all else you, if you have the form (or a list of all forms), you can iterate over the RTTI of the form.

You may have to recursively go over the RTTI of controls on the form (e.g. for tframe, maybe others).


So depending on the above is your question: How to iterate the RTTI?

Mind that there is also RegisterClass and such classes can be gotten from some list. But that may just mean, the unit that does the registration is used, the class itself may or may not be in use.


Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10897
  • Debugger - SynEdit - and more
    • wiki
Re: How to enumerate all TObject types used in a project?
« Reply #5 on: February 03, 2024, 05:32:21 pm »
Quote
To get the UnitName for

If you have the class, then there is
Code: Pascal  [Select][+][-]
  1. class function UnitName : string

so if you have "var TheClass: TClass" you can call that.

vfclists

  • Hero Member
  • *****
  • Posts: 1147
    • HowTos Considered Harmful?
Re: How to enumerate all TObject types used in a project?
« Reply #6 on: February 03, 2024, 06:31:46 pm »
You can read the resource of a lazarus EXE file to obtain the LFM string.

What utilities can be used for this?

Text editors general choke on such files
Lazarus 3.0/FPC 3.2.2

jamie

  • Hero Member
  • *****
  • Posts: 6811
Re: How to enumerate all TObject types used in a project?
« Reply #7 on: February 03, 2024, 06:44:42 pm »
it will only show what the designer put in there, runtime creation of components will not show in the LFM file or resource within the EXE.
The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018