如何在右键单击任何菜单项时获取 MenuItem 名称?

How to get the MenuItem name when right-clicking any menu item?

在 Delphi 11 VCL 应用程序 Windows 10 中,当右键单击任何菜单项时,我需要获取单击的菜单项的名称。

我使用 TApplicationEvents 组件和此代码在我单击任何菜单项时收到通知:

procedure TformMain.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
begin
  case Msg.message of
    Winapi.Messages.WM_COMMAND:
      begin
        CodeSite.Send('TformMain.ApplicationEvents1Message: WM_COMMAND');
      end;
  end;
end;

但是:

  1. 如何仅在右键单击菜单项时收到通知?

  2. 如何获取被点击的MenuItem的NAME?

每个 TMenu(即 TMainMenuTPopupMenu)提供一个方法 FindItem,它允许您通过不同的标准查找项目。在您的情况下,对表单主菜单的正确调用是

TheMenuItem := Menu.FindItem(Msg.wParam, fkCommand);

由于我的应用程序中有多个表单,每个表单上都有多个(弹出)菜单,因此这里需要一个特殊的解决方案:

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
begin
  case Msg.message of
      Winapi.Messages.WM_COMMAND:
      begin
        // Todo: Check HERE for RightMouseButtonDown - BUT HOW? (Or how to check HERE for modifier keys?)

        var ThisMenuItem := GetMenuItem(Msg.wParam);
        if Assigned(ThisMenuItem) then
        begin
          CodeSite.Send('TForm1.ApplicationEvents1Message: Clicked MenuItem Name', ThisMenuItem.Name);
        end;

      end;
  end;
end;

function TForm1.GetMenuItem(const aWParam: NativeUInt): TMenuItem;
var
  ThisMenuItem: TMenuItem;
begin
  Result := nil;
  var ThisForm := Screen.ActiveForm; // works on any form in the application
  for var i := 0 to ThisForm.ComponentCount - 1 do
  begin
    if ThisForm.Components[i] is TMenu then
    begin
      ThisMenuItem := TMenu(ThisForm.Components[i]).FindItem(aWParam, fkCommand);
      if Assigned(ThisMenuItem) then
      begin
        Result := ThisMenuItem;
        EXIT;
      end;
    end;
  end;
end;