среда, 5 июня 2013 г.

Маленький нюанс MethodAddress

Иногда во Free Pascal / Lazarus бывает нужно динамически устанавливать обработчики событий — имеем объект и имя свойства-события и устанавливаем через SetMethodProp(). В ряде мест можно встретить инструкции делать примерно так:

var
  meth : TMethod;
. . . . .
meth.Data = MyHandlerObject;
meth.Code = MyHandlerObject.MethodAddress('HandlerMethod');
SetMethodProp(Reciever, 'onEvent', meth);

А оно не работает. Потому, например, что HandlerMethod() невиртуальный. В общем, не надо тут усложнять, если имя метода известно при компиляции. Всё просто:

SetMethodProp(Receiver, 'onEvent', TMethod(@MyHandlerObject.HandlerMethod));

Может так статься, что объект, инкапсулирующий обработчик, нами автоматически создается и принадлежит нами же определенному классу, тогда может быть удобно определить (вероятно, виртуальный) метод для получения данных о методе:

type
  TMyHandlerObject = class(TAbstractHandler)
    procedure HandlerMethod (Sender : TObject); // TNotifyEvent
    function GetHandler : TMethod; override;
  end

. . . . .

function TMyHandlerObject.GetHandler : TMethod;
 begin
  result := TMethod(@self.HandlerMethod);
 end;

Это лучше, чем виртуализировать сам обработчик, если события (и, соответственно, обрабатывающие их методы) могут быть разных типов.

Комментариев нет:

Отправить комментарий