How to use TValue.AsType <TNotifyEvent>?
I am trying to use RTTI to add an event handler to a control that can already have an event handler installed. The code looks something like this:
var
prop: TRttiProperty;
val: TValue;
begin
prop := FContext.GetType(MyControl.ClassInfo).GetProperty('OnChange');
val := prop.GetValue(MyControl);
FOldOnChange := val.AsType<TNotifyEvent>;
prop.SetValue(MyControl, TValue.From<TNotifyEvent>(self.MyOnChange));
end;
I want this to be possible in MyOnChange:
begin
if assigned(FOldOnChange) then
FOldOnChange(Sender);
//additional code here
end;
Unfortunately, the compiler is not like a string FOldOnChange := val.AsType<TNotifyEvent>;. It says:
E2010 Incompatible types: 'procedure, untyped pointer or untyped parameter' and 'TNotifyEvent "
Does anyone know why this is or how to fix it? It seems to me...
+3
2 answers
FOldOnChange , AsType<TNotifyEvent> - . , . , () , , FOldOnChange.
:
uses SysUtils, Rtti;
type
TEv = procedure(Sender: TObject) of object;
TObj = class
private
FEv: TEv;
public
property Ev: TEv read FEv write FEv;
class procedure Meth(Sender: TObject);
end;
class procedure TObj.Meth(Sender: TObject);
begin
end;
procedure P;
var
ctx: TRttiContext;
t: TRttiType;
p: TRttiProperty;
v: TValue;
o: TObj;
e: TEv;
begin
t := ctx.GetType(TObj);
p := t.GetProperty('Ev');
o := TObj.Create;
try
// Set value explicitly
o.Ev := TObj.Meth;
// Get value via RTTI
v := p.GetValue(o);
//e := v.AsType<TEv>; // doesn't work
e := v.AsType<TEv>(); // works
finally
o.Free;
end;
end;
begin
try
P;
except
on e: Exception do
Writeln(e.Message);
end;
end.
+6
RTTI, 2010 , RTTI TypInfo ( ). TypInfo TMethod. ():
var
prop: TRttiProperty;
val: TValue;
evt: TNotifyEvent;
begin
prop := FContext.GetType(MyControl.ClassInfo).GetProperty('OnChange');
val := prop.GetValue(MyControl);
TMethod(FOldOnChange) := val.AsType<TMethod>;
evt := Self.MyOnChange;
prop.SetValue(MyControl, TValue.From<TMethod>(TMethod(evt));
end;
+1