Narcis Petru
Narcis Petru

Reputation: 33

Runtime creation of Delphi Firemonkey components from a string

How can i create at runtime a visual component as a child of the form using eventually RTTI? All i got is a TValue instance...

 t := (ctx.FindType(Edit1.Text) as TRttiInstanceType);
 inst:= t.GetMethod('Create').Invoke(t.MetaclassType,[Form1]);

Thank you!

Upvotes: 0

Views: 450

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 597560

A purely RTTI approach using TRttiMethod.Invoke() would look something like this:

var
  ctx: TRttiContext;
  t: TRttiInstanceType;
  m: TRttiMethod;
  params: TArray<TRttiParameter>;
  v: TValue;
  inst: TControl;
begin
  t := ctx.FindType(Edit1.Text) as TRttiInstanceType;
  if t = nil then Exit;
  if not t.MetaclassType.InheritsFrom(TControl) then Exit;
  for m in t.GetMethods('Create') do
  begin
    if not m.IsConstructor then Continue;
    params := m.GetParameters;
    if Length(params) <> 1 then Continue;
    if params[0].ParamType.Handle <> TypeInfo(TComponent) then Continue;
    v := m.Invoke(t.MetaclassType, [TComponent(Form1)]);
    inst := v.AsType<TControl>();
    // or: inst := TControl(v.AsObject);
    Break;
  end;
  inst.Parent := ...;
  ...
end;

A much simpler approach that does not use TRttiMethod.Invoke() would look like this:

type
  // TControlClass is defined in VCL, but not in FMX
  TControlClass = class of TControl;

var
  ctx: TRttiContext;
  t: TRttiInstanceType;
  inst: TControl;
begin
  t := ctx.FindType(Edit1.Text) as TRttiInstanceType;
  if t = nil then Exit;
  if not t.MetaclassType.InheritsFrom(TControl) then Exit;
  inst := TControlClass(t.MetaclassType).Create(Form4);
  inst.Parent := ...;
  //...
end;

Upvotes: 1

Related Questions