P.S. A working sample from my GUI code that exploits this:
(inspited by web programming in JavaScript I use for living)
Code:
TEventSubscriptionMethodType = (
esmt_simple, //a method with no parameters
esmt_string //a method receiving single UnicodeString
);
TEventSubscription = record
Receiver: TChepersyObject ;
Method: AnsiString;
MethodType: TEventSubscriptionMethodType;
DefaultString: UnicodeString;
end;
function TControl.PassEvent(var ES: TEventSubscription; w: UnicodeString): boolean;
type tmethod_with_str_par = procedure(slf: TObject; par: UnicodeString);
var
method: procedure(slf: TObject);
rclass: CChepersyObject;
//method_with_str_par: procedure(slf: TObject; par: ansistring) //#$%@#. It compiles, works, but code completion is shoot >:( absolute method; //har har, two variables accupying the same address Ain't I clever?
//a hack: calling orbitrary class method by its string name.
//watch the parameter list! (shall either be none or one ansistring,
//with ClickReceiverParam either nil or a non-empty string accordingly!)
begin
if not Assigned(ES.Receiver) then begin
//...irrelevant to this topic
end
else begin
if w = '' then w:= ES.DefaultString;
Result:= Yes;
pointer(method):= ES.Receiver.MethodAddress(ES.Method);
if not Assigned(pointer(method)) then begin
AddLog(RuEn(
'Класс %0: не удалось передать событие, подписчик (%1) не имеет метода "%2" '#13' параметр: "%3"',
'Class %0: failed to pass event, the subscriber (%1) doesn''t have a method "%2" '#13' parameter "%3"'),
[self.ClassName, ES.Receiver.Classname, ES.Method, w]);
Exit(No);
end;
try
if ES.MethodType = esmt_simple then method(ES.Receiver)
else begin
tmethod_with_str_par(method)(ES.Receiver, w);
end;
except
Die(RuEn(
'Крах класса %0 при вызове подписчика события, %1.%2(%3)',
'Class %0 crashed at calling the event subscriber %1.%2(%3)'),
[self.ClassName, ES.Receiver.Classname, ES.Method, w])
end;
end;
end;
Bookmarks