Windows系统菜单操作类:(建一个类,直接复制下面内容进行覆盖)
using
System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.ComponentModel;
namespace WindowSystemMenu
{
/// <summary>
/// 菜单类型
/// </summary>
public enum MenuItemFlag
{
/// <summary>
/// 两列带分割竖线
/// </summary>
MF_BARBREAK = 0x20 ,
/// <summary>
/// 两列无分割竖线
/// </summary>
MF_BREAK = 0x40 ,
/// <summary>
/// 居于底部
/// </summary>
MF_BYCOMMAND = 0 ,
/// <summary>
/// 居于顶部
/// </summary>
MF_BYPOSITION = 0x400 ,
/// <summary>
/// 前面具有对号
/// </summary>
MF_CHECKED = 8 ,
/// <summary>
/// 残缺
/// </summary>
MF_DISABLED = 2 ,
/// <summary>
/// 变灰(无法响应事件)
/// </summary>
MF_GRAYED = 1 ,
MF_POPUP = 0x10 ,
/// <summary>
/// 分割线
/// </summary>
MF_SEPARATOR = 0x800 ,
MF_STRING = 0 ,
/// <summary>
/// 不选择(无对号)
/// </summary>
MF_UNCHECKED = 0
}
internal class NativeMethods
{
public const uint LastMenuID = uint .MaxValue;
public static readonly IntPtr TRUE;
public const int WM_SYSCOMMAND = 0x112 ;
static NativeMethods()
{
TRUE = new IntPtr( 1 );
}
public NativeMethods()
{
}
[DllImport( " user32.dll " , SetLastError = true )]
public static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport( " user32.dll " , SetLastError = true )]
public static extern bool InsertMenu(IntPtr hMenu, uint wPosition, int wFlags, int wIDNewItem, string lpNewItem);
}
/// <summary>
/// Windows系统菜单
/// </summary>
public class NativeWindowMenu : NativeWindow, IDisposable
{
private IntPtr _hMenu;
private Dictionary < int , EventHandler > _menuClickEventList;
private Form _owner;
/// <summary>
/// 构造方法
/// </summary>
/// <param name="owner"></param>
public NativeWindowMenu(Form owner)
{
this ._owner = owner;
base .AssignHandle(owner.Handle);
this .GetSystemMenu();
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
base .ReleaseHandle();
this ._owner = null ;
this ._hMenu = IntPtr.Zero;
if ( this ._menuClickEventList != null )
{
this ._menuClickEventList.Clear();
this ._menuClickEventList = null ;
}
}
/// <summary>
/// 根据窗口句柄获得IntPtr
/// </summary>
private void GetSystemMenu()
{
this ._hMenu = NativeMethods.GetSystemMenu( base .Handle, false );
if ( this ._hMenu == IntPtr.Zero)
throw new Win32Exception( " 获取系统菜单失败。 " );
}
/// <summary>
/// 插入靠上的分割线
/// </summary>
/// <returns></returns>
public bool InertTopSeparator()
{
return this .InsertMenu( uint .MinValue, 0 , MenuItemFlag.MF_SEPARATOR | MenuItemFlag.MF_BYPOSITION, "" , null );
}
/// <summary>
/// 插入靠下的分割线
/// </summary>
/// <returns></returns>
public bool InertBottomSeparator()
{
return this .InsertMenu( uint .MaxValue, 0 , MenuItemFlag.MF_SEPARATOR | MenuItemFlag.MF_BYPOSITION, "" , null );
}
/// <summary>
/// 插入靠上的菜单
/// </summary>
/// <param name="Id"> 标识(范围0, 0xf000) </param>
/// <param name="Text"> 菜单显示文本 </param>
/// <param name="MenuClickEvent"> 菜单触发的事件 </param>
/// <returns></returns>
public bool InsertTopMenu( int Id, string Text, EventHandler MenuClickEvent)
{
return this .InsertMenu( uint .MinValue, Id, MenuItemFlag.MF_BYPOSITION, Text, MenuClickEvent);
}
/// <summary>
/// 插入靠下的菜单
/// </summary>
/// <param name="Id"> 标识(范围0, 0xf000) </param>
/// <param name="Text"> 菜单显示文本 </param>
/// <param name="MenuClickEvent"> 菜单触发的事件 </param>
/// <returns></returns>
public bool InsertBottomMenu( int Id, string Text, EventHandler MenuClickEvent)
{
return this .InsertMenu( uint .MaxValue, Id, MenuItemFlag.MF_BYPOSITION, Text, MenuClickEvent);
}
/// <summary>
/// 插入系统菜单
/// </summary>
/// <param name="Position"> 位置(uint.MaxValue:靠下;uint.MinValue:靠上.) </param>
/// <param name="Id"> 标识(范围0, 0xf000) </param>
/// <param name="Mif"> 菜单类型 </param>
/// <param name="Text"> 菜单显示文本 </param>
/// <param name="MenuClickEvent"> 菜单触发的事件 </param>
/// <returns></returns>
public bool InsertMenu( uint Position, int Id, MenuItemFlag Mif, string Text, EventHandler MenuClickEvent)
{
if ( ! (((Mif & MenuItemFlag.MF_SEPARATOR) == MenuItemFlag.MF_SEPARATOR) || this .ValidateID(Id)))
throw new ArgumentOutOfRangeException( " id " , string .Format( " 菜单ID只能在{0}-{1}之间取值。 " , 0 , 0xf000 ));
bool flag = NativeMethods.InsertMenu( this ._hMenu, Position, ( int )Mif, Id, Text);
if (flag && (MenuClickEvent != null ))
this .MenuClickEventList.Add(Id, MenuClickEvent);
return flag;
}
/// <summary>
/// 还原窗口句柄
/// </summary>
public void Revert()
{
NativeMethods.GetSystemMenu( base .Handle, true );
this .Dispose();
}
/// <summary>
/// 判断Id值是否符合要求
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
private bool ValidateID( int Id)
{
return ((Id < 0xf000 ) && (Id > 0 ));
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
protected override void WndProc( ref Message m)
{
if (m.Msg == 0x112 )
{
this .OnWmSysCommand( ref m);
}
else
{
base .WndProc( ref m);
}
}
private void OnWmSysCommand( ref Message m)
{
EventHandler handler;
int key = m.WParam.ToInt32();
if ( this .MenuClickEventList.TryGetValue(key, out handler))
{
if (handler != null )
{
handler( this , EventArgs.Empty);
}
m.Result = NativeMethods.TRUE;
}
else
{
base .WndProc( ref m);
}
}
/// <summary>
/// 菜单事件泛型
/// </summary>
protected Dictionary < int , EventHandler > MenuClickEventList
{
get
{
if ( this ._menuClickEventList == null )
{
this ._menuClickEventList = new Dictionary < int , EventHandler > ( 10 );
}
return this ._menuClickEventList;
}
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.ComponentModel;
namespace WindowSystemMenu
{
/// <summary>
/// 菜单类型
/// </summary>
public enum MenuItemFlag
{
/// <summary>
/// 两列带分割竖线
/// </summary>
MF_BARBREAK = 0x20 ,
/// <summary>
/// 两列无分割竖线
/// </summary>
MF_BREAK = 0x40 ,
/// <summary>
/// 居于底部
/// </summary>
MF_BYCOMMAND = 0 ,
/// <summary>
/// 居于顶部
/// </summary>
MF_BYPOSITION = 0x400 ,
/// <summary>
/// 前面具有对号
/// </summary>
MF_CHECKED = 8 ,
/// <summary>
/// 残缺
/// </summary>
MF_DISABLED = 2 ,
/// <summary>
/// 变灰(无法响应事件)
/// </summary>
MF_GRAYED = 1 ,
MF_POPUP = 0x10 ,
/// <summary>
/// 分割线
/// </summary>
MF_SEPARATOR = 0x800 ,
MF_STRING = 0 ,
/// <summary>
/// 不选择(无对号)
/// </summary>
MF_UNCHECKED = 0
}
internal class NativeMethods
{
public const uint LastMenuID = uint .MaxValue;
public static readonly IntPtr TRUE;
public const int WM_SYSCOMMAND = 0x112 ;
static NativeMethods()
{
TRUE = new IntPtr( 1 );
}
public NativeMethods()
{
}
[DllImport( " user32.dll " , SetLastError = true )]
public static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport( " user32.dll " , SetLastError = true )]
public static extern bool InsertMenu(IntPtr hMenu, uint wPosition, int wFlags, int wIDNewItem, string lpNewItem);
}
/// <summary>
/// Windows系统菜单
/// </summary>
public class NativeWindowMenu : NativeWindow, IDisposable
{
private IntPtr _hMenu;
private Dictionary < int , EventHandler > _menuClickEventList;
private Form _owner;
/// <summary>
/// 构造方法
/// </summary>
/// <param name="owner"></param>
public NativeWindowMenu(Form owner)
{
this ._owner = owner;
base .AssignHandle(owner.Handle);
this .GetSystemMenu();
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
base .ReleaseHandle();
this ._owner = null ;
this ._hMenu = IntPtr.Zero;
if ( this ._menuClickEventList != null )
{
this ._menuClickEventList.Clear();
this ._menuClickEventList = null ;
}
}
/// <summary>
/// 根据窗口句柄获得IntPtr
/// </summary>
private void GetSystemMenu()
{
this ._hMenu = NativeMethods.GetSystemMenu( base .Handle, false );
if ( this ._hMenu == IntPtr.Zero)
throw new Win32Exception( " 获取系统菜单失败。 " );
}
/// <summary>
/// 插入靠上的分割线
/// </summary>
/// <returns></returns>
public bool InertTopSeparator()
{
return this .InsertMenu( uint .MinValue, 0 , MenuItemFlag.MF_SEPARATOR | MenuItemFlag.MF_BYPOSITION, "" , null );
}
/// <summary>
/// 插入靠下的分割线
/// </summary>
/// <returns></returns>
public bool InertBottomSeparator()
{
return this .InsertMenu( uint .MaxValue, 0 , MenuItemFlag.MF_SEPARATOR | MenuItemFlag.MF_BYPOSITION, "" , null );
}
/// <summary>
/// 插入靠上的菜单
/// </summary>
/// <param name="Id"> 标识(范围0, 0xf000) </param>
/// <param name="Text"> 菜单显示文本 </param>
/// <param name="MenuClickEvent"> 菜单触发的事件 </param>
/// <returns></returns>
public bool InsertTopMenu( int Id, string Text, EventHandler MenuClickEvent)
{
return this .InsertMenu( uint .MinValue, Id, MenuItemFlag.MF_BYPOSITION, Text, MenuClickEvent);
}
/// <summary>
/// 插入靠下的菜单
/// </summary>
/// <param name="Id"> 标识(范围0, 0xf000) </param>
/// <param name="Text"> 菜单显示文本 </param>
/// <param name="MenuClickEvent"> 菜单触发的事件 </param>
/// <returns></returns>
public bool InsertBottomMenu( int Id, string Text, EventHandler MenuClickEvent)
{
return this .InsertMenu( uint .MaxValue, Id, MenuItemFlag.MF_BYPOSITION, Text, MenuClickEvent);
}
/// <summary>
/// 插入系统菜单
/// </summary>
/// <param name="Position"> 位置(uint.MaxValue:靠下;uint.MinValue:靠上.) </param>
/// <param name="Id"> 标识(范围0, 0xf000) </param>
/// <param name="Mif"> 菜单类型 </param>
/// <param name="Text"> 菜单显示文本 </param>
/// <param name="MenuClickEvent"> 菜单触发的事件 </param>
/// <returns></returns>
public bool InsertMenu( uint Position, int Id, MenuItemFlag Mif, string Text, EventHandler MenuClickEvent)
{
if ( ! (((Mif & MenuItemFlag.MF_SEPARATOR) == MenuItemFlag.MF_SEPARATOR) || this .ValidateID(Id)))
throw new ArgumentOutOfRangeException( " id " , string .Format( " 菜单ID只能在{0}-{1}之间取值。 " , 0 , 0xf000 ));
bool flag = NativeMethods.InsertMenu( this ._hMenu, Position, ( int )Mif, Id, Text);
if (flag && (MenuClickEvent != null ))
this .MenuClickEventList.Add(Id, MenuClickEvent);
return flag;
}
/// <summary>
/// 还原窗口句柄
/// </summary>
public void Revert()
{
NativeMethods.GetSystemMenu( base .Handle, true );
this .Dispose();
}
/// <summary>
/// 判断Id值是否符合要求
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
private bool ValidateID( int Id)
{
return ((Id < 0xf000 ) && (Id > 0 ));
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
protected override void WndProc( ref Message m)
{
if (m.Msg == 0x112 )
{
this .OnWmSysCommand( ref m);
}
else
{
base .WndProc( ref m);
}
}
private void OnWmSysCommand( ref Message m)
{
EventHandler handler;
int key = m.WParam.ToInt32();
if ( this .MenuClickEventList.TryGetValue(key, out handler))
{
if (handler != null )
{
handler( this , EventArgs.Empty);
}
m.Result = NativeMethods.TRUE;
}
else
{
base .WndProc( ref m);
}
}
/// <summary>
/// 菜单事件泛型
/// </summary>
protected Dictionary < int , EventHandler > MenuClickEventList
{
get
{
if ( this ._menuClickEventList == null )
{
this ._menuClickEventList = new Dictionary < int , EventHandler > ( 10 );
}
return this ._menuClickEventList;
}
}
}
}
Form中调用代码段:
#region
重构菜单
/// <summary>
/// 引发CreateControl事件时绘制菜单
/// </summary>
protected override void OnCreateControl()
{
base .OnCreateControl();
if (_NativeWindowMenu == null )
_NativeWindowMenu = new NativeWindowMenu( this );
_NativeWindowMenu.InertBottomSeparator();
_NativeWindowMenu.InsertBottomMenu( 1000 , " 关于(&A)... " , delegate ( object sender, EventArgs e) { this .About_Click(sender, e); });
_NativeWindowMenu.InsertBottomMenu( 1001 , " 作者博客(&B...) " , delegate ( object sender, EventArgs e) { this .AnthorBlog_Click(sender, e); });
}
/// <summary>
/// 句柄被销毁时释放NativeWindowMenu
/// </summary>
/// <param name="e"></param>
protected override void OnHandleDestroyed(EventArgs e)
{
base .OnHandleDestroyed(e);
if (_NativeWindowMenu != null )
{
_NativeWindowMenu.Dispose();
_NativeWindowMenu = null ;
}
}
#endregion
/// <summary>
/// 引发CreateControl事件时绘制菜单
/// </summary>
protected override void OnCreateControl()
{
base .OnCreateControl();
if (_NativeWindowMenu == null )
_NativeWindowMenu = new NativeWindowMenu( this );
_NativeWindowMenu.InertBottomSeparator();
_NativeWindowMenu.InsertBottomMenu( 1000 , " 关于(&A)... " , delegate ( object sender, EventArgs e) { this .About_Click(sender, e); });
_NativeWindowMenu.InsertBottomMenu( 1001 , " 作者博客(&B...) " , delegate ( object sender, EventArgs e) { this .AnthorBlog_Click(sender, e); });
}
/// <summary>
/// 句柄被销毁时释放NativeWindowMenu
/// </summary>
/// <param name="e"></param>
protected override void OnHandleDestroyed(EventArgs e)
{
base .OnHandleDestroyed(e);
if (_NativeWindowMenu != null )
{
_NativeWindowMenu.Dispose();
_NativeWindowMenu = null ;
}
}
#endregion