Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to trigger action when use mouse middle click on TPopupMenu's items?

Tags:

delphi

We use mouse left click to trigger actions in menu items of TPopupMenu. How to trigger different action on mouse middle click in these menu items? In other word, mouse left and middle click on TPopupmenu's menu items are both different action.

like image 450
Chau Chee Yang Avatar asked Jan 27 '26 05:01

Chau Chee Yang


1 Answers

The global Menus.PopupList variable keeps track of all PopupMenus and handles all massages send to them. You can override this PopupList with your own instance, as follows:

type
  TMyPopupList = class(TPopupList)
  private
    FMenuItem: TMenuItem;
  protected
    procedure WndProc(var Message: TMessage); override;
  end;

{ TMyPopupList }

procedure TMyPopupList.WndProc(var Message: TMessage);
var
  FindKind: TFindItemKind;
  I: Integer;
  Item: Integer;
  Action: TBasicAction;
  Menu: TMenu;
begin
  case Message.Msg of
    WM_MENUSELECT:
      with TWMMenuSelect(Message) do
      begin
        FindKind := fkCommand;
        if MenuFlag and MF_POPUP <> 0 then
          FindKind := fkHandle;
        for I := 0 to Count - 1 do
        begin
          if FindKind = fkHandle then
          begin
            if Menu <> 0 then
              Item := GetSubMenu(Menu, IDItem)
            else
              Item := -1;
          end
          else
            Item := IDItem;
          FMenuItem := TPopupMenu(Items[I]).FindItem(Item, FindKind);
          if FMenuItem <> nil then
            Break;
        end;
      end;
    WM_MBUTTONUP:
      if FMenuItem <> nil then
      begin
        GetMenuItemSecondAction(FMenuItem, Action);
        Menu := FMenuItem.GetParentMenu;
        if Action <> nil then
        begin
          Menu := FMenuItem.GetParentMenu;
          SendMessage(Menu.WindowHandle, WM_IME_KEYDOWN, VK_ESCAPE, 0);
          Action.Execute;
          Exit;
        end;
      end;
  end;
  inherited WndProc(Message);
end;

initialization
  PopupList.Free;
  PopupList := TMyPopupList.Create;

The GetMenuItemSecondAction routine you have to write yourself. Maybe this answer provides some help about adding your own actions to a component.

Note that the code under WM_MENUSELECT is simply copied from Menus.TPopupList.WndProc. You could also retrieve the MenuItem in the WM_MBUTTONUP handling by using MenuItemFromPoint.

But as the many comments have already said: think twice (or more) before implementing this UI functionality.

like image 78
NGLN Avatar answered Jan 28 '26 22:01

NGLN



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!