2009-10-13 102 views
4

我在MSDN上发现了一个thread,它显示了如何将项添加到winform标题栏的上下文菜单中。不幸的是,它不显示如何注册一个事件与自定义菜单项,我一直无法弄清楚如何做到这一点。以下是可以复制并粘贴到新的Windows Forms应用程序中的示例应用程序。如果有人能为我完成样品,我将不胜感激。谢谢将自定义上下文菜单项添加到Windows窗体标题栏

using System; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 

      IntPtr hMenu = GetSystemMenu(Handle, false); 
      if (hMenu != IntPtr.Zero) 
      { 
       var menuInfo = new MENUITEMINFO 
        { 
         cbSize = (uint) Marshal.SizeOf(typeof (MENUITEMINFO)), 
         cch = 255, 
         dwTypeData = "Test Item", 
         fMask = 0x1 | 0x2 | 0x10, 
         fState = 0, 
         fType = 0x0 
        }; 

       InsertMenuItem(hMenu, 0, true, ref menuInfo); 
       DrawMenuBar(Handle); 
      } 
     } 

     [DllImport("user32.dll")] 
     static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); 
     [DllImport("user32.dll")] 
     static extern bool DrawMenuBar(IntPtr hWnd); 
     [DllImport("user32.dll")] 
     static extern bool InsertMenuItem(IntPtr hMenu, uint uItem, 
          bool fByPosition, [In] ref MENUITEMINFO lpmii); 


     [StructLayout(LayoutKind.Sequential)] 
     public struct MENUITEMINFO 
     { 
      public uint cbSize; 
      public uint fMask; 
      public uint fType; 
      public uint fState; 
      public uint wID; 
      public IntPtr hSubMenu; 
      public IntPtr hbmpChecked; 
      public IntPtr hbmpUnchecked; 
      public IntPtr dwItemData; 
      public string dwTypeData; 
      public uint cch; 
      public IntPtr hbmpItem; 
     } 
    } 
} 

回答

8

您必须重写WndProc方法并拦截您的新菜单的id。

试试这个

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

namespace WindowsFormsApplication11 
{ 
    public partial class Form1 : Form 
    { 
    public const Int32 WM_SYSCOMMAND = 0x112; 
    public const Int32 MF_BYPOSITION = 0x400; 
    public const Int32 MYMENU1 = 1000; 
    public const Int32 MUMENU2 = 1001; 

    [DllImport("user32.dll")] 
    private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); 
    [DllImport("user32.dll")] 
    private static extern bool InsertMenu(IntPtr hMenu,Int32 wPosition, Int32 wFlags, Int32 wIDNewItem,string lpNewItem);  

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    protected override void WndProc(ref Message msg) 
    { 
     if (msg.Msg == WM_SYSCOMMAND) 
     { 
     switch (msg.WParam.ToInt32()) 
     { 
      case MYMENU1: 
      MessageBox.Show("Hi from My Menu 1¡¡¡¡"); 
      return; 
      case MUMENU2: 
      MessageBox.Show("Hi from My Menu 2¡¡¡¡"); 
      return; 
      default: 
      break; 
     } 
     } 
     base.WndProc(ref msg); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     IntPtr MenuHandle = GetSystemMenu(this.Handle, false); 
     InsertMenu(MenuHandle, 5, MF_BYPOSITION, MYMENU1, "My Menu 1"); 
     InsertMenu(MenuHandle, 6, MF_BYPOSITION, MUMENU2, "My Menu 2"); 
    } 
    } 
} 
3

对于分离只需添加:

public const Int32 MF_SEPARATOR = 0x800; 

和Form_load中:

InsertMenu(MenuHandle, 7, MF_BYPOSITION | MF_SEPARATOR, 0, string.Empty); // <-- Add a menu seperator 
0

我继续,只是添加了必要的元素,样例代码注册WndProc。这回答了注册WndProc的基本问题,而不像以前的解决方案那样改变代码。 (它将添加的菜单保留在系统菜单的顶部)。

using System; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 
{ 
public partial class Form1 : Form 
{ 
      public Form1() 
    { 
     InitializeComponent(); 

     IntPtr hMenu = GetSystemMenu(Handle, false); 
     if (hMenu != IntPtr.Zero) 
     { 
      var menuInfo = new MENUITEMINFO 
      { 
       cbSize = (uint)Marshal.SizeOf(typeof(MENUITEMINFO)), 
       cch = 255, 
       dwTypeData = "Test Item", 
       fMask = 0x1 | 0x2 | 0x10, 
       fState = 0, 
       // Add an ID for your Menu Item 
       wID = 0x1, 
       fType = 0x0 
      }; 

      InsertMenuItem(hMenu, 0, true, ref menuInfo); 
      DrawMenuBar(Handle); 
     } 
    } 

    [DllImport("user32.dll")] 
    static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); 
    [DllImport("user32.dll")] 
    static extern bool DrawMenuBar(IntPtr hWnd); 
    [DllImport("user32.dll")] 
    static extern bool InsertMenuItem(IntPtr hMenu, uint uItem, 
         bool fByPosition, [In] ref MENUITEMINFO lpmii); 


    [StructLayout(LayoutKind.Sequential)] 
    public struct MENUITEMINFO 
    { 
     public uint cbSize; 
     public uint fMask; 
     public uint fType; 
     public uint fState; 
     public uint wID; 
     public IntPtr hSubMenu; 
     public IntPtr hbmpChecked; 
     public IntPtr hbmpUnchecked; 
     public IntPtr dwItemData; 
     public string dwTypeData; 
     public uint cch; 
     public IntPtr hbmpItem; 
    } 

    // Add ID for the Menu 
    private const int WM_SYSCOMMAND = 0x112; 
    // Event method for the Menu 
    protected override void WndProc(ref Message m) 
    { 
     base.WndProc(ref m); 
              //m.WParam = the wID you gave the Menu Item 
     if ((m.Msg == WM_SYSCOMMAND) && ((int)m.WParam == 0x1)) 
     { 
      MessageBox.Show("Test Item Dialog"); 
     } 

    } 
} 

}

相关问题