How can I see who triggered an action in Delphi?

前端 未结 7 1332
别那么骄傲
别那么骄傲 2021-02-05 12:42

When a TAction event fires, the \"Sender\" is always the action itself. Usually that\'s the most useful, but is it somehow possible to find out who triggered the action\'s OnExe

相关标签:
7条回答
  • 2021-02-05 13:11

    I have a bunch of panels and I want to let the user right click any of those panels and perform a "delete file" action. So, I have a single pop-up menu associated with all those panels. This is how I find out which panel was right clicked:

    (Note: I put lots of comments to clearly explain how it works. But if you don't like it, you can compactify the code to 2 lines (see the second procedure)).

    So, if you have actions assigned to that pop-up menu:

    procedure Tfrm.actDelExecute(Sender: TObject);
    VAR
      PopMenu: TPopupMenu;
      MenuItem: TMenuItem;
      PopupComponent: TComponent;
    begin
     { Find the menuitem associated to this action }
     MenuItem:= TAction(Sender).ActionComponent as TMenuItem;  { This will crash and burn if we call this from a pop-up menu, not from an action! But we always use actions, so.... }
    
     { Was this action called by keyboard shortcut? Note: in theory there should be no keyboard shortcuts for this action if the action can be applyed to multiple panels. We can call this action ONLY by selecting (right click) a panel! }
     if MenuItem = NIL then
      begin
       MsgError('This action should not be called by keyboard shortcuts!');
       EXIT;
      end;
    
     { Find to which pop-up menu this menuitem belongs to }
     PopMenu:= (MenuItem.GetParentMenu as TPopupMenu);
    
     { Find on which component the user right clicks }
     PopupComponent := PopMenu.PopupComponent;
    
     { Finally, access that component }
     (PopupComponent as TMonFrame).Delete(FALSE);
    end;
    

    If you only have a simple pop-up menu (no actions assigned):

    procedure Tfrm.actDelHddExecute(Sender: TObject);
    VAR PopupComponent: TComponent;
    begin
     PopupComponent := ((Sender as TMenuItem).GetParentMenu as TPopupMenu).PopupComponent;
     (PopupComponent as TMonFrame).Delete(TRUE);
    end;
    

    You can put all that code in a single function that returns a TPanel and call it like this:

    procedure Tfrm.actDelWallExecute(Sender: TObject);
    begin
     if GetPanelFromPopUp(Sender) <> NIL
     then GetPanelFromPopUp(Sender).Delete(FALSE);
    end;
    
    0 讨论(0)
提交回复
热议问题