Reputation: 302
I want to draw some themes parts to several TImages. In my code below, GetElementDetails
expects a certain enum value. I have the PTypeInfo
for the enum type, but I don't know how to type-cast i
to the enum type.
procedure TForm1.Button1Click(Sender: TObject);
procedure drawType(c: tcanvas; ti: ptypeinfo);
var
r: trect;
i: integer;
details: TThemedElementDetails;
begin
r.Left := 0; r.Top := 0; r.Right := 19; r.Bottom := 19;
for i := GetTypeData(ti).MinValue to GetTypeData(ti).MaxValue do begin
// How to cast i to the enum type of ti?
details := StyleServices.GetElementDetails( ???(i) );
StyleServices.DrawElement(c.Handle, details, R);
if (i mod 10 = 0) and (i > 0) then begin
r.Left := 0; r.Right := 19; r.Top := r.Bottom + 3; r.Bottom := r.Bottom + 22;
end
else r.Inflate(-22,0,22,0);
end;
end;
begin
drawType(image1.canvas, typeinfo(TThemedToolBar));
drawType(image2.canvas, typeinfo(TThemedButton));
drawType(image3.canvas, typeinfo(TThemedCategoryPanelGroup));
drawType(image4.canvas, typeinfo(TThemedComboBox));
end;
I need to cast i
to the type passed as second variable (TThemedToolBar
, TThemedButton
, etc.). How can I solve this?
Upvotes: 5
Views: 234
Reputation: 709
try this one:
type
TAbstractStyleServicesFunction = reference to function(const styleServices: TAbstractStyleServices; const I: Integer)
: TThemedElementDetails;
procedure TForm1.drawType(c: TCanvas; ti: PTypeInfo; const styleServicesFunction: TAbstractStyleServicesFunction);
var
r: trect;
I: Integer;
begin
r.Left := 0;
r.Top := 0;
r.Right := 19;
r.Bottom := 19;
for I := GetTypeData(ti).MinValue to GetTypeData(ti).MaxValue do
begin
styleServices.DrawElement(c.Handle, styleServicesFunction(styleServices, I), r);
if (I mod 10 = 0) and (I > 0) then
begin
r.Left := 0;
r.Right := 19;
r.Top := r.Bottom + 3;
r.Bottom := r.Bottom + 22;
end
else
r.Inflate(-22, 0, 22, 0);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
drawType(image1.canvas, typeinfo(TThemedToolBar),
function(const styleServices: TAbstractStyleServices; const I: Integer): TThemedElementDetails
begin
Result := styleServices.GetElementDetails(TThemedToolBar(I));
end);
end;
Upvotes: 4
Reputation: 613612
You cannot do this easily. The GetElementDetails
method is overloaded heavily on its first parameters. Overload resolution is static, performed at compile time. You wish to bind to the method at runtime, based on the run time type of the enum. That's not possible for normal method calls.
The only way to do this is with RTTI. Enumerate the methods of the style services object. Find all the ones that have the name GetElementDetails
. Pick the one whose parameters match the run time type of your enum. Then call it using RTTI.
I can't write any code to show you this, but there are plenty of good examples of these techniques, now that you know what needs to be done.
Upvotes: 2