Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何以编程方式显示主菜单的子菜单?_C#_.net_Winforms_Mainmenu - Fatal编程技术网

C# 如何以编程方式显示主菜单的子菜单?

C# 如何以编程方式显示主菜单的子菜单?,c#,.net,winforms,mainmenu,C#,.net,Winforms,Mainmenu,我需要以编程方式在Winform.NΕtth应用程序(classesMainMenuwithMenuItem)的窗体上显示主菜单的子菜单 例如,显示包含菜单项文件所有项的子菜单 例如,如果菜单项文本为&File,则与按Alt-F相同 我试图调用OnPopup(),PerformClick(),PerformSelect(),并发送WM\u MenuSelect消息;子菜单未打开 有办法吗?您需要将所需的菜单项克隆到表单构造函数或加载事件中的新ContextMenu组件,并将其附加到目标控件的

我需要以编程方式在Winform.NΕtth应用程序(classes
MainMenu
with
MenuItem
)的窗体上显示主菜单的子菜单

  • 例如,显示包含菜单项文件所有项的子菜单
  • 例如,如果菜单项文本为&File,则与按Alt-F相同
我试图调用
OnPopup()
PerformClick()
PerformSelect()
,并发送
WM\u MenuSelect
消息;子菜单未打开


有办法吗?

您需要将所需的菜单项克隆到表单构造函数或加载事件中的新
ContextMenu
组件,并将其附加到目标控件的
ContextMenu
(而不是
ContextMenuStrip
)属性

例如,要将“文件”菜单中的“新建”、“打开”和“保存”项克隆到新的
上下文菜单中

var cmn=new ContextMenu();
cmn.MenuItems.AddRange(
新[]
{
mnuFileNew.CloneMenu(),
mnuFileOpen.CloneMenu(),
mnuFileSave.clonemenus()
}
);
或者,如果您需要它们:

mnuFile.MenuItems.Cast<MenuItem>().ToList()
    .ForEach(m => cmn.MenuItems.Add(m.CloneMenu()));

现在,右键单击表单,新的
上下文菜单将弹出,单击一个项目,相同的代码将被执行。

您需要将所需的菜单项克隆到表单构造函数或加载事件中的新的
上下文菜单组件,并将其附加到
上下文菜单
(不是
上下文菜单
)目标控件的属性

例如,要将“文件”菜单中的“新建”、“打开”和“保存”项克隆到新的
上下文菜单中

var cmn=new ContextMenu();
cmn.MenuItems.AddRange(
新[]
{
mnuFileNew.CloneMenu(),
mnuFileOpen.CloneMenu(),
mnuFileSave.clonemenus()
}
);
或者,如果您需要它们:

mnuFile.MenuItems.Cast<MenuItem>().ToList()
    .ForEach(m => cmn.MenuItems.Add(m.CloneMenu()));

现在,右键单击表单,将弹出新的
上下文菜单
,单击一个项目,将执行相同的代码。

要显示旧组件的菜单项,需要调用菜单项句柄并将其传递给它。要将其显示在正确的位置,如单击菜单项时,请使用获取菜单项矩形

代码如下:

[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);
注意:建议使用 而不是
主菜单


要显示旧组件的菜单项,需要调用菜单项句柄并将其传递给它。要将其显示在正确的位置,如单击菜单项时,请使用获取菜单项矩形

代码如下:

[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);
注意:建议使用 而不是
主菜单


应该是这些旧组件的标签
mainmenu
contextmenu
,…等等。我为
mainmenu
创建了一个标记。应该是这些旧组件的标记
mainmenu
contextmenu
,…等等。我为
mainmenu
创建了一个标记。与往常一样漂亮,感谢您添加标记。与往常一样漂亮,感谢您添加标记。