2009-10-13 72 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"); 
     } 

    } 
} 

}

相關問題