Supporting Set Types via RTTI

This code demonstrates how you can use your TraRTTI descendants to provide support for Set type properties without using Sets.

Version 1.0 of RAP does not support Set types. However, it is possible, using RTTI, to supply support for Set type properties.  Take, for instance, TFont’s Style property which is of type TFontStyles – a set. In order to support this property via RAP, we have added some boolean properties to TFont in the TraTFontRTTI
class, a TraRTTI descendant. Since TFontStyles is a set of fsBold, fsItalic, fsUnderline and fsStrikeout, we have added Bold, Italic, Underline and Strikeout to TFont. In this manner, you can set the boolean properties in RAP and the TraFontRTTI class handles transferring these values to and from the Style property in Delphi’s TFont. The following code demonstrates this.

Note: If you are unfamiliar with registering classes with RAP via TraRTTI descendants, you should aquaint yourself with the process by completing the Extending the RAP RTTI tutorial in the RAP help file.

First we declare a new TraRTTI descendant, TraTFontRTTI, to provide the new properties.

In GetPropList and GetPropRec, we add the new properties.

In GetPropValue, we transfer values from Delphi’s TFont.Style property to the boolean properties:

class function TraTFontRTTI.GetPropValue(aObject: TObject; const aPropName: String; var aValue): Boolean;
begin
  ...
  else if ppEqual(aPropName, 'Italic') then
    {if fsItalic is in Style then set TFont.Italic to True}
    Boolean(aValue) := (fsItalic in TFont(aObject).Style)
  ...
end;

In TraTFontRTTI.SetPropValue, we transfer values from our new properties to Delphi’s TFont.Style property:

class function TraTFontRTTI.SetPropValue(aObject: TObject; const aPropName: String; var aValue): Boolean;
var
  lFontStyles: TFontStyles;
begin
  ...
  lFontStyles := TFont(aObject).Style;
  ...
  else if ppEqual(aPropName, 'Italic') then
    begin
      {if TFont.Italic then add fsItalic to Style...}
      if (Boolean(aValue)) then
        include(lFontStyles, fsItalic)
      else
        exclude(lFontStyles, fsItalic);

      TFont(aObject).Style := lFontStyles;
    end
  ...
end;