分享

操作Windows系统菜单 - HappyNale(海蓓娜楽) - 博客园

 唐伯龙 2011-04-12

操作Windows系统菜单

2010-08-25 09:54 by 海蓓娜楽, 10 visits, 网摘, 收藏, 编辑

 

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}之间取值。"00xf000));
            
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

 

 

源码下载

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多