Reputation: 3809
I'm using Delphi 5, and we have a method to dynamically create certain controls based on the contents of a database table (we create TButtons mostly) and take action when those are clicked. This allows us to add simple controls to a form without having to recompile the application.
I was wondering if it was possible to set a component's property based on a property name contained in a string so we could set further options.
Pseudo-code:
Comp := TButton.Create(Self);
// Something like this:
Comp.GetProperty('Left').AsInteger := 100;
// Or this:
Comp.SetProperty('Left', 100);
Is this possible at all?
Upvotes: 7
Views: 10077
Reputation: 72504
You have to use the Run-Time Type Information features of Delphi to do this:
This blog describes exactly what you are trying to do: Run-Time Type Information In Delphi - Can It Do Anything For You?
Basically you have to get the property information, using GetPropInfo
and then use SetOrdProp
to set the value.
uses TypInfo;
var
PropInfo: PPropInfo;
begin
PropInfo := GetPropInfo(Comp.ClassInfo, 'Left');
if Assigned(PropInfo) then
SetOrdProp(Comp, PropInfo, 100);
end;
This is not as concise as your pseudo-code, but it still does the job. Also it gets more complicated with other stuff, like array properties.
Upvotes: 15
Reputation: 3242
Just as an added example. Here is how to set sub-properties, I'm setting the Margins on this Button component:
uses TypInfo;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
var PropInfo := GetPropInfo(Button1.ClassInfo, 'Margins');
if Assigned(PropInfo) then
begin
var Margins := TMargins.Create(self);
try
Margins.Left := 100;
Margins.Top := 100;
Margins.Right := 100;
Margins.Bottom := 100;
SetObjectProp(Button1, PropInfo, Margins);
finally
Margins.Free;
end;
end;
end;
This works on Delphi 10.3 Rio and later due to the inline variables.
Upvotes: 0
Reputation: 5058
From one of my working units (in Delphi 7 though)
var
c : TComponent;
for i := 0 to pgcProjectEdits.Pages[iPage].ControlCount - 1 do
begin
c := pgcProjectEdits.Pages[iPage].Controls[i];
if c is TWinControl
then begin
if IsPublishedProp(c,'color')
then
SetPropValue(c,'color',clr);
if IsPublishedProp(c,'readonly')
then
SetPropValue(c,'readonly', bReadOnly );
...
end;
...
You have to include TypInfo
in the uses statement.
Don't know if this works under Delphi 5.
Upvotes: 10