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

1

7

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.

Mastin answered 10/8, 2017 at 21:30 Comment(0)
N
11

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.

Newburg answered 10/8, 2017 at 21:55 Comment(3)
thanx for clarification... the only way to workaround, is to change record to object, I seeMastin
Yes, and make sure it derives from TPersistent or a descendant of it.Newburg
Actually, my answer was a little misleading. It IS possible in Delphi 7, but it is probably not the solution you are hoping for. I have updated my answer.Newburg

© 2022 - 2024 — McMap. All rights reserved.