⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 specialmenuprovider.cs

📁 c#编写的汽车销售公司erp进销存系统
💻 CS
📖 第 1 页 / 共 2 页
字号:
				SizeF sz;
				Font fnt=
					inf.Item.DefaultItem?new Font(e.Font,FontStyle.Bold):
					SystemInformation.MenuFont;//set font to BOLD if Item is a DefaultItem
				if (inf.Item.Text!="")
				{
					sz=e.Graphics.MeasureString(inf.Item.Text,fnt);//draw text
					e.Graphics.DrawString(inf.Item.Text,fnt,
						inf.Disabled?Brushes.Gray:Brushes.Black,
						inf.Rct.X+inf.Rct.Height+5,
						inf.Rct.Y+(inf.Rct.Height-(int)sz.Height)/2,fmt);
				}	
				if (inf.Item.Shortcut!=Shortcut.None && inf.Item.ShowShortcut)
				{
					string shc=GetShortcutString((Keys)inf.Item.Shortcut);

					sz=e.Graphics.MeasureString(shc,fnt);//draw shortcut
					e.Graphics.DrawString(shc,fnt,
						inf.Disabled?Brushes.Gray:Brushes.Black,
						inf.Rct.Right-(int)sz.Width-16,
						inf.Rct.Y+(inf.Rct.Height-(int)sz.Height)/2);
				}
				#endregion
			}
		}
		#endregion
		#region provideproperty::NewStyleActive
		/// <summary>
		/// Specifies wheter NewStyle-Drawing is enabled or not
		/// </summary>
		[Description("Specifies wheter NewStyle-Drawing is enabled or not")]
		[Browsable(false)]
		public bool GetNewStyleActive(MenuItem control) 
		{
			return true;//make sure every new item is selected
		}
		/// <summary>
		/// Specifies wheter NewStyle-Drawing is enabled or not
		/// </summary>
		public void SetNewStyleActive(MenuItem control, bool value) 
		{
			if (!value) 
			{
				if (_menuitems.Contains(control))//remove it from the collection
				{
					_menuitems.Remove(control);
				}
				//reset to system drawing
				control.OwnerDraw=false;
				control.MeasureItem-=new MeasureItemEventHandler(control_MeasureItem);
				control.DrawItem-=new DrawItemEventHandler(control_DrawItem);
			}
			else 
			{
				//add it or change the value
				if (!_menuitems.Contains(control))
					_menuitems.Add(control,new MenuItemInfo(true,null));
				else
					((MenuItemInfo)_menuitems[control]).NewStyle=true;
				//set to owner drawing
				control.OwnerDraw=true;
				control.MeasureItem+=new MeasureItemEventHandler(control_MeasureItem);
				control.DrawItem+=new DrawItemEventHandler(control_DrawItem);
			}
		}
		#endregion
		#region provideproperty::MenuGlyph
		/// <summary>
		/// Specifies the image displayed next to the MenuItem
		/// </summary>
		[Description("Specifies the image displayed next to the MenuItem")]
		[DefaultValue(null)]
		public Image GetMenuGlyph(MenuItem control) 
		{
			MenuItemInfo ret=(MenuItemInfo)_menuitems[control];
			if (ret==null) return null;
			return ret.Glyph;
		}
		/// <summary>
		/// Specifies the image displayed next to the MenuItem
		/// </summary>
		public void SetMenuGlyph(MenuItem control, Image value) 
		{
			if (value==null) 
			{
				if (_menuitems.Contains(control))//set the image property in the collection to NULL
				{
					((MenuItemInfo)_menuitems[control]).Glyph=null;
					if(((MenuItemInfo)_menuitems[control]).NewStyle==false)
						_menuitems.Remove(control);
				}			
			}
			else 
			{
				//add the MenuItem to the collection or change the image value
				if (!_menuitems.Contains(control))
				{
					_menuitems.Add(control,new MenuItemInfo(true,value));
					control.OwnerDraw=true;
					control.MeasureItem+=new MeasureItemEventHandler(control_MeasureItem);
					control.DrawItem+=new DrawItemEventHandler(control_DrawItem);
				}
				else
					((MenuItemInfo)_menuitems[control]).Glyph=value;
					
			}
		}
		#endregion

		#region hooker
		[Browsable(false)]
		public Form OwnerForm
		{
			get{return _owner;}
			set
			{
				if (_hook!=IntPtr.Zero)//uninstall hook
				{
					Win32.UnhookWindowsHookEx(_hook);
					_hook=IntPtr.Zero;
				}
				_owner = value;
				if (_owner != null)
				{
					if (_hookprc == null)
					{
						_hookprc = new Win32.HookProc(OnHookProc);
					}
					_hook = Win32.SetWindowsHookEx(Win32.WH_CALLWNDPROC,//install hook
						_hookprc, IntPtr.Zero, Win32.GetWindowThreadProcessId(_owner.Handle, 0));
				}
			}
		}
		/// <summary>
		/// process all message posted to the application
		/// </summary>
		private int OnHookProc(int code, IntPtr wparam, ref Win32.CWPSTRUCT cwp)
		{
			if (code == 0)
			{
				switch (cwp.message)
				{
					case Win32.WM_CREATE://a window is created
					{
						StringBuilder builder1 = new StringBuilder(0x40);
						int num2 = Win32.GetClassName(cwp.hwnd, builder1, builder1.Capacity);
						string text1 = builder1.ToString();
						if (string.Compare(text1,"#32768",false) == 0)//test if the class name
							//identifies the control as a MenuItem
						{
							this.lastHook = new MenuHook(this,_lastwidth);
							this.lastHook.AssignHandle(cwp.hwnd);
							_lastwidth=0;
							/*
							 * We don't use a local variable, because the GC
							 * would destroy it immediately afte leaving the
							 * function. Instead we use one private variable
							 * ,because there's always only  one ContextMenu
							 * on the  Desktop and  the Hooker is  destroyed
							 * when another ContextMenu lights up.
							 */
						}
						break;
					}
					case Win32.WM_DESTROY://owner is destroyed, unhook all
					{
						if ((cwp.hwnd == _owner.Handle) && _hook!=IntPtr.Zero)
						{
							Win32.UnhookWindowsHookEx(_hook);
							_hook = IntPtr.Zero;
						}
						break;
					}
				}
			}
			return Win32.CallNextHookEx(_hook, code, wparam, ref cwp);
		}
		#endregion
		#region helper
		/// <summary>
		/// gets the brush to draw the image-band next to each menuitem
		/// </summary>
		[Browsable(false)]
		public LinearGradientBrush MarginBrush
		{
			get
			{
				lnbrs.LinearColors=_cols[0];
				lnbrs.Transform=new Matrix(_margin,0f,0f,1f,1f,0f);
				return lnbrs;
			}
		}
		/// <summary>
		/// gets the width of the image-band next to each menuitem
		/// </summary>
		[Browsable(false)]
		public int MarginWidth
		{
			get{return _margin;}
		}
		/// <summary>
		/// returns the Pen used to paint the border of a menuitem
		/// </summary>
		[Browsable(false)]
		public Pen BorderPen
		{
			get{return border;}
		}
		private string GetShortcutString(Keys shortcut)
		{
			return TypeDescriptor.GetConverter(typeof(Keys))
				.ConvertToString(shortcut);
		}
		#endregion
		#region public properties
		/// <summary>
		/// the color of the border of the selection frame and the popup menu itself
		/// </summary>
		[DefaultValue(typeof(Color),"0,0,128")]
		[Category("Colors")]
		[Description("the color of the border of the selection frame and the popup menu itself")]
		public Color BorderColor
		{
			get{return border.Color;}
			set{border.Color=Color.FromArgb(255,value);}
		}
		/// <summary>
		/// specifies the lighter color of a preselected menuitem
		/// </summary>
		[DefaultValue(typeof(Color),"255,244,204")]
		[Category("Colors")]
		[Description("specifies the lighter color of a preselected menuitem")]
		public Color HotLightGradientLight
		{
			get{return _cols[2][0];}
			set{_cols[2][0]=Color.FromArgb(255,value);}
		}
		/// <summary>
		/// specifies the darker color of a preselected menuitem
		/// </summary>
		[DefaultValue(typeof(Color),"255,214,154")]
		[Category("Colors")]
		[Description("specifies the darker color of a preselected menuitem")]
		public Color HotLightGradientDark
		{
			get{return _cols[2][1];}
			set{_cols[2][1]=Color.FromArgb(255,value);}
		}
		/// <summary>
		/// the color on the right side of a mainmenu
		/// </summary>
		[DefaultValue(typeof(Color),"195,218,249")]
		[Category("Colors")]
		[Description("the color on the right side of a mainmenu")]
		public Color BandGradientLight
		{
			get{return _cols[1][0];}
			set{_cols[1][0]=Color.FromArgb(255,value);}
		}
		/// <summary>
		/// the color on the left side of a mainmenu
		/// </summary>
		[DefaultValue(typeof(Color),"158,190,245")]
		[Category("Colors")]
		[Description("the color on the left side of a mainmenu")]
		public Color BandGradientDark
		{
			get{return _cols[1][1];}
			set{_cols[1][1]=Color.FromArgb(255,value);}
		}
		/// <summary>
		/// sets or gets the lighter color of the image-band next to each menuitem
		/// </summary>
		[DefaultValue(typeof(Color),"227,239,255")]
		[Category("Colors")]
		[Description("sets or gets the lighter color of the image-band next to each menuitem")]
		public Color ItemGradientLight
		{
			get{return _cols[0][0];}
			set{_cols[0][0]=Color.FromArgb(255,value);}
		}
		/// <summary>
		/// sets or gets the darker color of the image-band next to each menuitem
		/// </summary>
		[DefaultValue(typeof(Color),"135,173,228")]
		[Category("Colors")]
		[Description("sets or gets the darker color of the image-band next to each menuitem")]
		public Color ItemGradientDark
		{
			get{return _cols[0][1];}
			set{_cols[0][1]=Color.FromArgb(255,value);}
		}
		#endregion
	}
	/// <summary>
	/// This class is used to hook the events posted to a context/popup menu
	/// </summary>
	internal class MenuHook:NativeWindow
	{
		#region variablen
		private SpecialMenuProvider _parent=null;
		private int _lastwidth=0;
		#endregion
		public MenuHook(SpecialMenuProvider parent, int lastwidth)
		{
			if (parent==null)
				throw new ArgumentNullException();//parent property mustn't be NULL
			_parent=parent;//MenuExtender with drawing paramenters
			_lastwidth=lastwidth;//width of the topItem unfolding the Menu or 0
		}
		#region controller
		/// <summary>
		/// Hook window messages of a context/popup menu
		/// </summary>
		/// <param name="m">windows message</param>
		protected override void WndProc(ref Message m)
		{
			switch(m.Msg)
			{
				case Win32.WM_NCPAINT://menu unfolding
				{
					IntPtr windc = Win32.GetWindowDC(m.HWnd);
					Graphics gr = Graphics.FromHdc(windc);
					this.DrawBorder(gr);
					Win32.ReleaseDC(m.HWnd, windc);
					gr.Dispose();
					m.Result = IntPtr.Zero;
					break;
				}
				case Win32.WM_PRINT://user presses 'PRINT'
				{
					base.WndProc(ref m);
					IntPtr dc = m.WParam;
					Graphics gr = Graphics.FromHdc(dc);
					this.DrawBorder(gr);
					Win32.ReleaseDC(m.HWnd, dc);
					gr.Dispose();
					break;
				}
				default:
				{
					base.WndProc(ref m);
					break;
				}
			}
		}
		#endregion
		/// <summary>
		/// This draws the missing parts in the margin of a menuitem
		/// </summary>
		/// <param name="gr">the graphics surface to draw on</param>
		private void DrawBorder(Graphics gr)
		{
			//calculate the space of the context/popup menu
			Rectangle clip=Rectangle.Round(gr.VisibleClipBounds);
			clip.Width--; clip.Height--;

			int margin=_parent.MarginWidth;
			//fill the missing gradient parts using extender's brush
			gr.FillRectangle(_parent.MarginBrush,clip.X+1,clip.Y+1,2,clip.Height-2);
			gr.FillRectangle(_parent.MarginBrush,clip.X+1,clip.Y+1,margin,2);
			gr.FillRectangle(_parent.MarginBrush,clip.X+1,clip.Bottom-2,margin,2);

			//fill the other edges white, so using old windows style will not change the appearance
			gr.FillRectangle(Brushes.White,clip.X+margin+1,clip.Y+1,clip.Width-margin-1,2);
			gr.FillRectangle(Brushes.White,clip.X+margin+1,clip.Bottom-2,clip.Width-margin-1,2);
			gr.FillRectangle(Brushes.White,clip.Right-2,clip.Y+1,2,clip.Height);

			//draw the border with a little white line on the top,
			//then it looks like a tab unfolding.
			//in contextmenus: _lastwidth==0
			gr.DrawLine(Pens.White,clip.X+1,clip.Y,clip.X+_lastwidth-2,clip.Y);
			gr.DrawLine(_parent.BorderPen,clip.X,clip.Y,clip.X,clip.Bottom);
			gr.DrawLine(_parent.BorderPen,clip.X,clip.Bottom,clip.Right,clip.Bottom);
			gr.DrawLine(_parent.BorderPen,clip.Right,clip.Bottom,clip.Right,clip.Y);
			gr.DrawLine(_parent.BorderPen,clip.Right,clip.Y,clip.X+_lastwidth-1,clip.Y);
		}
	}
	/// <summary>
	/// This class provides static access to some Win32 API
	/// </summary>
	internal abstract class Win32
	{
		[DllImport("user32.dll", CharSet=CharSet.Ansi, SetLastError=true, ExactSpelling=true)]
		public static extern int CallNextHookEx(IntPtr hookHandle, int code, IntPtr wparam, ref CWPSTRUCT cwp);
		[DllImport("user32.dll", EntryPoint="GetClassNameA", CharSet=CharSet.Ansi, SetLastError=true, ExactSpelling=true)]
		public static extern int GetClassName(IntPtr hwnd, StringBuilder className, int maxCount);
		[DllImport("user32", CharSet=CharSet.Ansi, SetLastError=true, ExactSpelling=true)]
		public static extern IntPtr GetWindowDC(IntPtr hwnd);
		[DllImport("user32.dll", CharSet=CharSet.Ansi, SetLastError=true, ExactSpelling=true)]
		public static extern int GetWindowThreadProcessId(IntPtr hwnd, int ID);
		[DllImport("user32", CharSet=CharSet.Ansi, SetLastError=true, ExactSpelling=true)]
		public static extern IntPtr ReleaseDC(IntPtr hwnd, IntPtr hdc);
		[DllImport("user32.dll", EntryPoint="SetWindowsHookExA", CharSet=CharSet.Ansi, SetLastError=true, ExactSpelling=true)]
		public static extern IntPtr SetWindowsHookEx(int type, HookProc hook, IntPtr instance, int threadID);
		[DllImport("user32.dll", CharSet=CharSet.Ansi, SetLastError=true, ExactSpelling=true)]
		public static extern bool UnhookWindowsHookEx(IntPtr hookHandle);

		public const int WH_CALLWNDPROC = 4;
		public const int WM_CREATE = 1;
		public const int WM_DESTROY = 2;
		public const int WM_NCPAINT = 0x85;
		public const int WM_PRINT = 0x317;

		[StructLayout(LayoutKind.Sequential)]
			public struct CWPSTRUCT
		{
			public IntPtr lparam;
			public IntPtr wparam;
			public int message;
			public IntPtr hwnd;
		}

		public delegate int HookProc(int code, IntPtr wparam, ref Win32.CWPSTRUCT cwp);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -