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.
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.