Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get property of the 'record' type using TypInfo unit

I have this record type

TDoublePoint = record
               X : Double;
               Y : Double;
               end;

then I have object with this property

uses ..TypInfo;

TCell = class(TPersistent)
  private
    FZoom : TDoublePoint 
  published
    property Zoom : TDoublePoint read FZoom write FZoom;
end;

But when I want to get PropInfo of this property with this function:

function GetKind(AObject:TObject; Propertyname :shortstring):TTypeKind;
var p :ppropinfo;
begin
  p:=GetPropInfo(AObject, Propertyname);  // <p = nil
  Result:= p^.proptype^.Kind;
end;

.. ..

c := TCell.Create;
GetKind(c, 'Zoom');  //   <- error
c.Free;

I get error, because variable p is nil in the function.

But Why? There is tkRecord in the TTypeKind, so I expected no problems to read/write the property of record type, but it seems, it is not possible (?) Google search did not tell much.

like image 967
lyborko Avatar asked Aug 10 '17 21:08

lyborko


1 Answers

Delphi 7 does not generate RTTI for a record type by default, and so a published property that uses a record type will not have RTTI, either (you can use TypInfo.GetPropList() to confirm that).

At one point, this was a documented limitation:

Published properties are restricted to certain data types. Ordinal, string, class, interface, variant, and method-pointer types can be published.

However, there is a workaround. IF a record type contains any compiler-managed data types (long strings, interfaces, dynamic arrays, etc), then RTTI will be generated for that record type, as will any published property that uses that record type, and thus GetPropInfo() can find such properties (I have confirmed that this does work in Delphi 7).

Your TDoublePoint record does not contain any compiler-managed data types, so that is why GetPropInfo() is returning nil for your TCell.Zoom property.

That RTTI issue was fixed in a later version (not sure which one. I'm guessing maybe in Delphi 2010, when Extended RTTI was first introduced). For instance, the code you have shown works for me as-is in XE. GetPropInfo() can find the Zoom property as expected, without having to introduce any compiler-managed types into the TDoublePoint record type.

like image 95
Remy Lebeau Avatar answered Nov 15 '22 05:11

Remy Lebeau