Search code examples
functiondelphidynamic-programmingfiremonkey

Delphi function SetProperty (ComponentName: string, PropertyName: string, JSONValue: string): boolean;


How would I go about to write a function that takes the name of a component and property and a JSON value string and populate that component's property with the value dynamically? The property can be a single value of a specific data type or it may be more complex, but for now let's stick to a single value property (string or integer or float).

Not sure where to start as this means grabbing a component based on the name dynamically.

I guess I might need to specify the component and property type as parameters as well like:

 function SetProperty(ComponentType, ComponentName, PropertyType, PropertyName: string; JSONValue: string): boolean;

What I do not know is how to reference this component dynamically in code.

An example would be:

result := SetProperty('TEdit', 'Edit1', 'Integer', 'Width', '{Value:100}');

Solution

  • I got it working. Here's my take on it! I only make provision for simple types for now, but that should be enough. (Thanks to jamesc for responding.)

    uses
      System.Rtti, System.TypInfo;
    
    function SetProperty (pComponentName, pPropertyName: string; pValue: string): boolean;
    var
      AComponent: TComponent;
      APropList: PPropList;
      APropCount: integer;
      APPropInfo: PPTypeInfo;
      APropInfo: TTypeInfo;
      I: integer;
    begin
      AComponent := Form1.FindComponent(pComponentName);
      if AComponent <> nil then
      begin
        APropCount := GetPropList(AComponent, APropList);
        try
          for I := 0 to APropCount - 1 do
          begin
            if APropList[I].Name = pPropertyName then
            begin
              APPropInfo := GetPropInfo(AComponent, pPropertyName).PropType;
              APropInfo := APPropInfo^^;
              if ((APropInfo.Kind = TTypeKind.tkInteger)
                 or (APropInfo.Kind = TTypeKind.tkChar)
                 or (APropInfo.Kind = TTypeKind.tkFloat)
                 or (APropInfo.Kind = TTypeKind.tkString)
                 or (APropInfo.Kind = TTypeKind.tkWChar)
                 or (APropInfo.Kind = TTypeKind.tkLString)
                 or (APropInfo.Kind = TTypeKind.tkWString)
                 or (APropInfo.Kind = TTypeKind.tkInt64)
                 or (APropInfo.Kind = TTypeKind.tkUString)) then
                SetPropValue(AComponent, pPropertyName, pValue);
            end;
          end;
        finally
          FreeMem(APropList);
        end;
      end;
    end;