Problem with DefineClassByRTTI

Hello,

I have problem with DefineClassByRTTI. If I use old DefineClass (old RTTI) I have got all inherited properties. For exmaple

DefineClass(TMyForm)

I have got published properties from TMyForm and TForm and TCustomForm etc. It's ok and expected

But when I use:

DefineClassByRTTI(TMyForm)

I see only published properties from TMyForm. I think problem is in DefineClass in TatClasses. There is

          // define properties
          if Options.CustomProperties then
            props := Options.Properties
          else
            props := rtype.GetDeclaredProperties; ----------------------------------- HERE
          for prop in props do
          begin
            if (prop <> nil) and (prop.Visibility in Options.VisibilityFilter) and (prop.PropertyType <> nil) then
            begin
              if prop.IsReadable then
                Getter := FScripter.GenericPropGetterMachineProc

and GetDeclaredProperties only lists properties in current class. If we need inherited properties also we have to use GetProperties. I have changed code on my side to:

          // define properties
          if Options.CustomProperties then
            props := Options.Properties
          else
            props := rtype.GetProperties; ---------------------- HERE
          for prop in props do
          begin
            if (prop <> nil) and (prop.Visibility in Options.VisibilityFilter) and (prop.PropertyType <> nil) then
            begin
              if prop.IsReadable then
                Getter := FScripter.GenericPropGetterMachineProc

This should work ok. I tested it and it works as expected. I think it's a bug in original code. Am I right?

Thank you

No, because the DefineClass already explicitly inherits the properties from ancestors classes in this code:

        if AClass.ClassParent <> nil then
        begin
          DefineClass(AClass.ClassParent, Options, AClass.ClassParent.ClassName);
          Result.FAncestorName := AClass.ClassParent.ClassName;
          if Result.FAncestorName > '' then
            Result.Inherits(Result.FAncestorName);
        end;

Are you at least seeing the published properties from ancestor classes?

I think not. DefineClass do not explicitly inherits properties defined using RTTI.

      { copia do ancestral, todos as propriedades definidas
        (exceto aquelas que foram definidas automaticamente pelo RTTI) }
      for c := 0 to FAncestor.FProperties.Count - 1 do
        if not Assigned(FAncestor.FProperties[c].FPropInfo) then  ------------- SEE HERE
        begin
          Prop := TatProperty(FProperties.Add);
          Prop.Assign(FAncestor.FProperties[c]);
          SetLibContext(Prop);
        end;

If I use DefineClassByRTTI I never see published properties from ancestor classes.

Can you please send a small project reproducing the issue?

testcase1.zip (53.0 KB)
In attachment. Build project, press Button3 and display library browser. Look at TForm1 properties.

Use this:

 IDEScripter1.DefineClassByRTTI(TForm1, TRedefineOption.roInclude);

It works partly. As side efect it also redefines all ancestors, but ok for now.
I still do not see all properties, for example TForm1.Caption

In this case, use roOverwrite:

 IDEScripter1.DefineClassByRTTI(TForm1, TRedefineOption.roOverwrite);

roOverwrite works ok.

Thank you

1 Like

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.