Search code examples
delphiembedded-resourcedelphi-11-alexandriadfmdelphi-12-athens

How to access dfm resource at runtime (Delphi 11, 12)


How can a DFM resource of a form in a Delphi project be accessed in code at runtime?

Background: I want to be able to parse a form's DFM at runtime to create HTML and other representations of it on demand. Of course, I could parse them before building the project and create an extra resource. But as they are compiled into the software and used at runtime I believe they should also be accessible somehow in code.

I currently use Delphi 11 and soon Delphi 12.


Solution

  • The RTL has classes and functions in the System.Classes unit for processing DFMs. After all, any Forms (or DataModules or Frames) in your project have to parse their own DFMs at runtime. That functionality is publicly accessible, so you can also parse DFMs yourself, too.

    To answer your specific question - you can use the TResourceStream class to access a DFM resource, using the ClassName of the Form/DataModule/Frame that the DFM belongs to.

    For example, when a TCustomForm-/TDataModule-/TCustomFrame-derived class loads its DFM at runtime:

    • its constructor calls InitInheritedComponent() ...

    • which calls InternalReadComponentRes(), passing in the target's ClassName and HInstance of the EXE/Package which its class is implemented in (that can be found using FindClassHInstance() and FindResourceHInstance()) ...

    • which creates a TResourceStream object using the specified HInstance and ClassName and RT_RCDATA resource type, and then calls its ReadComponent() method ...

    • which creates a TReader object using Self as its source stream, and then calls its ReadRootComponent() method to parse the stream data and populate the target's properties.

    You can use the TReader class directly in your own code for your own parsing needs. You don't have to read the DFM values into a target Form/DataModule/Frame object.