Delphi: Как вызвать метод, когда я щелкаю элемент управления? - PullRequest
1 голос
/ 13 мая 2010

у меня есть метод:

procedure Frob(Sender: TObject);

, на который я хочу позвонить, когда нажимаю на пункт меню.

Метод приходит ко мне через интерфейс:

animal: IAnimal;

IAnimal = interface
   procedure Frob(Sender: TObject);
end;

Вопрос заключается в том, что назначить обработчику событий OnClick элемента меню (т.е. элемента управления):

var
   animal: IAnimal;
   ...
begin
   ...
   menuItem := TMenuItem.Create(FileMenu)
   menuItem.Caption := 'Click me!';
   menuItem.OnClick :=  <-------- what to do
   ...
end;

Очевидный выбор, моя первая попытка, и неправильный ответ :

   menuItem.OnClick := animal.Frob;

Так как можно вызвать метод, когда пользователь щелкает элемент управления?

Смотри также

Ответы [ 3 ]

4 голосов
/ 14 мая 2010

Поместите любой объект, в котором вы находитесь, удерживайте животное в закрытом поле, затем настройте метод, который вызывает его.Вот так:

procedure TMyClass.AnimalFrob(Sender: TObject);
begin
   FAnimal.Frob(sender);
end;

Тогда решение становится легким:

menuItem.OnClick := self.AnimalFrob;

1 голос
/ 14 мая 2010

Я знаю, что вы пометили вопрос как ответ, но вот некоторые другие предложения:

  type
    IClicker = Interface
      function GetOnClickProc : TNotifyEvent;
    End;

  type
    TBlob = class( TInterfacedObject, IClicker )
      procedure OnClick( Sender : TObject );
      function GetOnClickProc : TNotifyEvent;
    end;

{ TBlob }

function TBlob.GetOnClickProc : TNotifyEvent;
begin
  Result := Self.OnClick;
end;

procedure TBlob.OnClick(Sender: TObject);
begin
  MessageDlg('Clicked !', mtWarning, [mbOK], 0);
end;

{ MyForm }
  var
    clicker : IClicker;

  begin
    ...
    menuItem.OnClick := clicker.GetOnClickProc;
  end;

Конечно, вы должны быть осторожны с временем жизни объекта "кликера" ...

Если вы можете управлять своими объектами как объектами (а не только как интерфейсами), попробуйте добавить общий подкласс:

type
  TClicker = class
    procedure OnClick( Sender : TObject ); virtual;
  end;

var
  lClicker : TClicker;
...
menuItem.OnClick := lClicker.OnClick;

Я бы также обратился за комментарием к Cosmin Prund: создайте специализированный подкласс TMenuItem.

1 голос
/ 14 мая 2010

Другой, немного хакерский подход - хранить ссылку на IAnimal в свойстве Tag объекта TMenuItem.

Это может быть индекс IAnimal в TList, как вы предложили:

if Sender is TMenuItem then
  IAnimal(FAnimals[TMenuItem(Sender).Tag]).Frob;

Или вы можете привести интерфейс к Integer.

MenuItem.Tag := Integer(AnAnimal);

Затем приведите обратно к IAnimal в обработчике событий:

if Sender is TMenuItem then
  IAnimal(TMenuItem(Sender)).Frob;

Это хорошо работает с объектными ссылками, может потребоваться некоторая осторожность с интерфейсами из-за подсчета ссылок.

Обратите внимание, что Delphi 7 также имеет TInterfaceList в Classes.pas

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...