Расширьте событие OnClick всех MenuItems на экране, чтобы выполнить другой блок кода - PullRequest
2 голосов
/ 02 апреля 2019

Я хочу установить событие OnClick для всех TMenuItems на экране, чтобы сделать то, что происходит в данный момент, и еще несколько строк кода. Я в настоящее время использую Delphi 5

Например, скажем, что у меня есть TMenuItem с кодом:

procedure TdesktopForm.MenuFoo1Click(Sender: TObject);
begin
  ShowMessage(TComponent(Sender).Name)
end;

и у меня также есть следующая процедура:

procedure TdesktopForm.bar;
begin
  ShowMessage('extra')
end;

И я хочу, чтобы каждый раз, когда я нажимал на TMenuItem, программа показывала имя TMenuItem, а также сообщение «extra».

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

Я пытался использовать TActionList, но я не смог получить объект, запускающий действие, поэтому я не могу напечатать его имя. Я пытался использовать ActiveControl, но он всегда возвращает сфокусированный в данный момент сфокусированный объект, а не фактическое меню, которое я щелкнул. А также, событие TAction execute перезаписывает мое TMainMenu.OnClick событие

1 Ответ

5 голосов
/ 02 апреля 2019

Пока все ваши обработчики событий назначены в какой-то момент (либо во время разработки, либо во время выполнения) и впоследствии не меняются, вы можете сделать что-то вроде этого:

  1. Перечислить всепункты меню в меню
  2. Для каждого создайте объект, подобный описанному ниже

    type
      TEventInterceptor = class(TComponent)
      private
        FOrigEvent: TNotifyEvent;
        FAdditionalEvent: TNotifyEvent;
        procedure HandleOnClick(_Sender: TObject);
      public
        constructor Create(_MenuItem: TMenuItem; _AdditionalEvent: TNotifyEvent);
      end;
    
    constructor TEventInterceptor.Create(_MenuItem: TMenuItem; _AdditionalEvent: TNotifyEvent);
    begin
      inherited Create(_MenuItem);
      FOrigEvent := _MenuItem.OnClick;
      FAdditionalEvent := _AdditionalEvent;
      _MenuItem.OnClick := HandleOnClick;
    end;
    
    procedure TEventInterceptor.HandleOnClick(_Sender: TObject);
    begin
      FOrigEvent(_Sender);
      FAdditinalEvent(_Sender);
    end;
    

Обратите внимание, что этот код полностью не проверен и может даже не проверятьсякомпиляции.Я также не уверен, работает ли это с Delphi 5. Это работает с Delphi 6, хотя, так что шансы хорошие.

Редактировать: Некоторые дополнительные заметки (спасибо за комментарии):

  • Наследование этого класса от TComponent автоматически освобождает форму при уничтожении.
  • Возможно, HandleOnClick должен проверять, назначен ли FOrigEvent перед вызовом.
...