[英]How to programmatically enable \ disable nested sub-menu items in a ToolStripMenuItem?
[英]How to show sub-menu of a MainMenu programmatically?
我需要以編程方式在 Winform .NET 應用程序中的表單上顯示主菜單的子菜單(使用MenuItem
類MainMenu
)。
我嘗試調用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);
注意:建議使用
MenuStrip
而不是MainMenu
。
您需要在 Form 的構造函數或 Load 事件中將所需的菜單項克隆到新的ContextMenu
組件,並將其附加到目標控件的ContextMenu
(而不是ContextMenuStrip
)屬性。
例如,要將File菜單中的New 、 Open和Save項目克隆到新的ContextMenu
:
var cmn = new ContextMenu();
cmn.MenuItems.AddRange(
new[]
{
mnuFileNew.CloneMenu(),
mnuFileOpen.CloneMenu(),
mnuFileSave.CloneMenu()
}
);
或者,如果您需要它們:
mnuFile.MenuItems.Cast<MenuItem>().ToList()
.ForEach(m => cmn.MenuItems.Add(m.CloneMenu()));
請注意,子項目也將被克隆(如果有)。
並將其分配給ContextMenu
屬性:
this.ContextMenu = cmn;
現在右鍵單擊窗體,新的ContextMenu
將彈出,單擊一個項目,將執行相同的代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.