2009-10-13 5 views
4

J'ai trouvé un thread sur MSDN qui montre comment ajouter un élément au menu contextuel d'une barre de titre winform. Malheureusement, il ne montre pas comment enregistrer un événement avec l'élément de menu personnalisé et j'ai été incapable de comprendre comment le faire. Voici un exemple d'application qui peut être copié et collé dans une nouvelle application Windows Forms. J'apprécierais que quelqu'un puisse compléter l'échantillon pour moi. MerciAjout d'un élément de menu contextuel personnalisé à la barre de titre Windows Form

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; 
     } 
    } 
} 

Répondre

8

Vous devez remplacer WndProc méthode et intercepter l'identifiant de votre nouveau menu.

essayer cette

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

Pour un séparateur il suffit d'ajouter:

public const Int32 MF_SEPARATOR = 0x800; 

et Form_load:

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

je suis allé de l'avant et juste ajouté les éléments nécessaires à l'exemple de code pour enregistrer le WndProc. Cela répond à la question fondamentale de l'enregistrement du WndProc sans altérer autant le code que la solution précédente. (Il conserve le menu ajouté en haut du menu système).

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"); 
     } 

    } 
} 

}

Questions connexes