SystemMenuNativeWindow.cs
上传用户:dzysfj
上传日期:2021-09-14
资源大小:118k
文件大小:6k
源码类别:

菜单

开发平台:

C#

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Windows.Forms;
  5. using System.ComponentModel;
  6. namespace CSharpWin
  7. {
  8.     /* 作者:Starts_2000
  9.      * 日期:2009-08-30
  10.      * 网站:http://www.csharpwin.com CS 程序员之窗。
  11.      * 你可以免费使用或修改以下代码,但请保留版权信息。
  12.      * 具体请查看 CS程序员之窗开源协议(http://www.csharpwin.com/csol.html)。
  13.      */
  14.     public class SystemMenuNativeWindow : NativeWindow, IDisposable
  15.     {
  16.         private Form _owner;
  17.         private IntPtr _hMenu;
  18.         private Dictionary<int, EventHandler> _menuClickEventList;
  19.         public SystemMenuNativeWindow(Form owner)
  20.         {
  21.             _owner = owner;
  22.             base.AssignHandle(owner.Handle);
  23.             GetSystemMenu();
  24.         }
  25.         protected Dictionary<int, EventHandler> MenuClickEventList
  26.         {
  27.             get
  28.             {
  29.                 if (_menuClickEventList == null)
  30.                 {
  31.                     _menuClickEventList = new Dictionary<int, EventHandler>(10);
  32.                 }
  33.                 return _menuClickEventList;
  34.             }
  35.         }
  36.         public bool InsertMenu(
  37.             int position, 
  38.             int id, 
  39.             string text,
  40.             EventHandler menuClickEvent)
  41.         {
  42.             return InsertMenu(
  43.                 position,
  44.                 id,
  45.                 MenuItemFlag.MF_BYPOSITION | MenuItemFlag.MF_STRING,
  46.                 text,
  47.                 menuClickEvent);
  48.         }
  49.         public bool InertSeparator(int position)
  50.         {
  51.             return InsertMenu(
  52.                 position,
  53.                 0,
  54.                 MenuItemFlag.MF_BYPOSITION | MenuItemFlag.MF_SEPARATOR,
  55.                 "",
  56.                 null);
  57.         }
  58.         public bool InsertMenu(
  59.             int position, 
  60.             int id, 
  61.             MenuItemFlag flag, 
  62.             string text,
  63.             EventHandler menuClickEvent)
  64.         {
  65.             if ((flag & MenuItemFlag.MF_SEPARATOR) != MenuItemFlag.MF_SEPARATOR &&
  66.                 !ValidateID(id))
  67.             {
  68.                 throw new ArgumentOutOfRangeException(
  69.                     "id",
  70.                     string.Format(
  71.                     "菜单ID只能在{0}-{1}之间取值。", 0, 0xF000));
  72.             }
  73.             bool sucess = NativeMethods.InsertMenu(
  74.                _hMenu,
  75.                position,
  76.                (int)flag,
  77.                id,
  78.                text);
  79.             if (sucess && menuClickEvent != null)
  80.             {
  81.                 MenuClickEventList.Add(id, menuClickEvent);
  82.             }
  83.             return sucess;
  84.         }
  85.         public bool AppendMenu(
  86.             int id, 
  87.             string text, 
  88.             EventHandler menuClickEvent)
  89.         {
  90.             return AppendMenu(
  91.                 id,
  92.                 MenuItemFlag.MF_BYPOSITION | MenuItemFlag.MF_STRING,
  93.                 text,
  94.                 menuClickEvent);
  95.         }
  96.         public bool AppendSeparator()
  97.         {
  98.             return AppendMenu(
  99.                 0,
  100.                 MenuItemFlag.MF_BYPOSITION | MenuItemFlag.MF_SEPARATOR,
  101.                 "",
  102.                 null);
  103.         }
  104.         public bool AppendMenu(
  105.             int id, 
  106.             MenuItemFlag flag, 
  107.             string text, 
  108.             EventHandler menuClickEvent)
  109.         {
  110.             if ((flag & MenuItemFlag.MF_SEPARATOR) != MenuItemFlag.MF_SEPARATOR &&
  111.                 !ValidateID(id))
  112.             {
  113.                 throw new ArgumentOutOfRangeException(
  114.                     "id",
  115.                     string.Format(
  116.                     "菜单ID只能在{0}-{1}之间取值。", 0, 0xF000));
  117.             }
  118.             bool sucess = NativeMethods.AppendMenu(
  119.                 _hMenu,
  120.                 (int)flag,
  121.                 id,
  122.                 text);
  123.             if (sucess && menuClickEvent != null)
  124.             {
  125.                 MenuClickEventList.Add(id, menuClickEvent);
  126.             }
  127.             return sucess;
  128.         }
  129.         public void Revert()
  130.         {
  131.             NativeMethods.GetSystemMenu(base.Handle, true);
  132.             Dispose();
  133.         }
  134.         protected override void WndProc(ref Message m)
  135.         {
  136.             switch (m.Msg)
  137.             {
  138.                 case NativeMethods.WM_SYSCOMMAND:
  139.                     OnWmSysCommand(ref m);
  140.                     break;
  141.                 default:
  142.                     base.WndProc(ref m);
  143.                     break;
  144.             }
  145.         }
  146.         private void GetSystemMenu()
  147.         {
  148.             _hMenu = NativeMethods.GetSystemMenu(base.Handle, false);
  149.             if (_hMenu == IntPtr.Zero)
  150.             {
  151.                 throw new Win32Exception("获取系统菜单失败。");
  152.             }
  153.         }
  154.         private bool ValidateID(int id)
  155.         {
  156.             return id < 0xF000 && id > 0;
  157.         }
  158.         private void OnWmSysCommand(ref Message m)
  159.         {
  160.             int id = m.WParam.ToInt32();
  161.             EventHandler handler;
  162.             if (MenuClickEventList.TryGetValue(id, out handler))
  163.             {
  164.                 if (handler != null)
  165.                 {
  166.                     handler(this, EventArgs.Empty);
  167.                 }
  168.                 m.Result = NativeMethods.TRUE;
  169.             }
  170.             else
  171.             {
  172.                 base.WndProc(ref m);
  173.             }
  174.         }
  175.         #region IDisposable 成员
  176.         public void Dispose()
  177.         {
  178.             base.ReleaseHandle();
  179.             _owner = null;
  180.             _hMenu = IntPtr.Zero;
  181.             if (_menuClickEventList != null)
  182.             {
  183.                 _menuClickEventList.Clear();
  184.                 _menuClickEventList = null;
  185.             }
  186.         }
  187.         #endregion
  188.     }
  189. }