我需要以编程方式在 Winform 中的窗体上显示主菜单的子菜单。NΕΤ 应用程序(类 MainMenu
和 MenuItem
)。
- 例如显示包含菜单项文件的所有项目的子菜单。
- 例如如果菜单项文本为 &File,则与按 Alt-F 相同。
我已尝试调用 OnPopup()
、PerformClick()
、PerformSelect()
并发送 WM_MenuSelect
留言;子菜单打不开。
有办法吗?
最佳答案
显示遗留菜单项 MainMenu
组件,你需要调用TrackPopupMenuEx
并将菜单项句柄传递给它。要在正确的位置显示它,就像您单击菜单项时一样,使用 GetMenuItemRect
获取菜单项矩形。 .
代码如下:
[DllImport("user32.dll")]
static extern int TrackPopupMenuEx(IntPtr hmenu, uint fuFlags,
int x, int y, IntPtr hwnd, IntPtr lptpm);
[DllImport("user32.dll")]
static extern bool GetMenuItemRect(IntPtr hWnd, IntPtr hMenu,
uint uItem, out RECT lprcItem);
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);
[StructLayout(LayoutKind.Sequential)]
public struct RECT { public int Left, Top, Right, Bottom; }
const int TPM_RIGHTBUTTON = 0x2;
const int TPM_RETURNCMD = 0x100;
const int WM_SYSCOMMAND = 0x112;
public void ShowSubMenu(MenuItem menuItem, bool asContextMenu = false)
{
var mainMenu = menuItem.GetMainMenu();
var form = mainMenu.GetForm();
var x = 0; var y = 0;
if (asContextMenu)
{
x = MousePosition.X; y = MousePosition.Y;
}
else
{
GetMenuItemRect(form.Handle, mainMenu.Handle,
(uint)menuItem.Index, out RECT rect);
x = rect.Left; y = rect.Bottom;
}
var command = TrackPopupMenuEx(menuItem.Handle, TPM_RETURNCMD | TPM_RIGHTBUTTON,
x, y, form.Handle, IntPtr.Zero);
if (command > 0)
SendMessage(form.Handle, WM_SYSCOMMAND, command, IntPtr.Zero);
}
要使用它,只需这样调用它:
ShowSubMenu(fileMenuItem);
如果您通过将 false 传递给 showAxContextMenu
来调用它,它将在鼠标位置显示子菜单:
ShowSubMenu(fileMenuItem, true);
Note: It's recommended to use a
MenuStrip
instead of aMainMenu
.
关于c# - 如何以编程方式显示 MainMenu 的子菜单?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59171718/