It's been a long while since I've written a Delphi component.

As I'm writing yet another Delphi component, this time, on MacOS, I find myself having to grapple with how component persistence works in Delphi.

When the Delphi RTL is loading or storing an instance of a component on a form, it reads the path of each property.

If the property does not have any property information (no PropInfo: this happens when the property is not published or has no RTTI), the RTL then calls Instance.DefineProperties (where Instance is an instance of the component currently being created). If the property has property information (is published or has RTTI), it is automatically persisted. So if there is a call to Filer.DefineProperty with an existing published property, then the property will be persisted twice.

In the component where the DefineProperties method is overridden, typically something like the following is seen:

  inherited DefineProperties(Filer);
  Filer.DefineProperty('SourcePoint', ReadSourcePoint, WriteSourcePoint, FShape = stComicCallout);

The RTL compares the first parameter (using the RTL function call SameText) to the property path. If it matches (it is case insensitive), it then calls the read method (specified by the developer), which in this case, is ReadSourcePoint.  The called method, ReadSourcePoint, reads the property value, interprets it, then stores it wherever it wants to. In this case, I stored it back into FSourcePoint.
WriteSourcePoint is the counterpart to ReadSourcePoint, and is used when the component is being persisted.