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

📄 richmenuitem.cs

📁 c#精彩编程百例(源代码)
💻 CS
字号:
//  RichMenuItem.cs
//  Copyright (c) 2001 Mike Krueger
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

using System;
using System.Drawing;
using System.Diagnostics;
using System.Drawing.Text;
using System.Drawing.Imaging;
using System.Windows.Forms;

using SharpDevelop.Gui.Window;
using SharpDevelop.Tool.Data;
using SharpDevelop.Internal.ExternalTool;
using SharpDevelop.Internal.Text;

namespace SharpDevelop.Gui.Components {
	
	public enum IconMenuStyle {
		Standard,
		Office2000,
		VSNet
	};
	
	public interface MenuItemStyleDrawer
	{
		void DrawCheckmark(Graphics g, Rectangle bounds, bool selected);
		void DrawIcon(Graphics g, Image icon, Rectangle bounds, bool selected, bool enabled, bool ischecked);
		void DrawSeparator(Graphics g, Rectangle bounds);
		void DrawBackground(Graphics g, Rectangle bounds, DrawItemState state, bool toplevel, bool hasicon);
		void DrawMenuText(Graphics g, Rectangle bounds, string text, string shortcut, bool enabled, bool toplevel, DrawItemState state);
	}
	
	public class Office2000Style : MenuItemStyleDrawer
	{
		static int TEXTSTART = 20;
		
		public void DrawCheckmark(Graphics g, Rectangle bounds, bool selected)
		{
			ControlPaint.DrawMenuGlyph(g, new Rectangle(bounds.X + 2, bounds.Y + 2, 14, 14), MenuGlyph.Checkmark);
		}
		
		public void DrawIcon(Graphics g, Image icon, Rectangle bounds, bool selected, bool enabled, bool ischecked)
		{
		    if (enabled) {
				g.DrawImage(icon, bounds.Left + 2, bounds.Top + 2);
		    } else
		    	ControlPaint.DrawImageDisabled(g, icon, bounds.Left + 2, bounds.Top + 2, SystemColors.Control);
   			
			if (selected)
		    	ControlPaint.DrawBorder3D(g, bounds.Left, bounds.Top, icon.Width + 3, icon.Height + 3, Border3DStyle.RaisedInner);
		}
		
		public void DrawSeparator(Graphics g, Rectangle bounds)
		{
			ControlPaint.DrawBorder3D(g, bounds.X, bounds.Y + 2, bounds.Width, 3, Border3DStyle.Etched, Border3DSide.Top);
		}
		
		public void DrawBackground(Graphics g, Rectangle bounds, DrawItemState state, bool toplevel, bool hasicon)
		{
			bool selected = (state & DrawItemState.Selected) > 0;
			if (selected ||((state & DrawItemState.HotLight) > 0)) {
				if (toplevel) {
		    		g.FillRectangle(SystemBrushes.Menu, bounds);
		    		ControlPaint.DrawBorder3D(g, bounds.Left, bounds.Top, bounds.Width, bounds.Height, selected ? Border3DStyle.SunkenOuter : Border3DStyle.RaisedInner, Border3DSide.All);
				} else {
					if (hasicon) {
					    g.FillRectangle(SystemBrushes.Menu, new Rectangle(bounds.X, bounds.Y, bounds.X + SystemInformation.SmallIconSize.Width + 5, bounds.Height));
						bounds.X += SystemInformation.SmallIconSize.Width + 5;
						bounds.Width -= SystemInformation.SmallIconSize.Width + 5;
					}
		    		g.FillRectangle(SystemBrushes.Highlight, bounds);
				}
			} else {
	    		g.FillRectangle(SystemBrushes.Menu, bounds);
			}
		}
		
		public void DrawMenuText(Graphics g, Rectangle bounds, string text, string shortcut, bool enabled, bool toplevel, DrawItemState state)
		{
			bool selected = (state & DrawItemState.Selected) > 0;
		    StringFormat stringformat = new StringFormat();
			stringformat.HotkeyPrefix = ((state & DrawItemState.NoAccelerator) > 0) ? HotkeyPrefix.Hide : HotkeyPrefix.Show;
			int textwidth = (int)(g.MeasureString(text, SystemInformation.MenuFont).Width);
			int x = toplevel ? bounds.Left + (bounds.Width - textwidth) / 2: bounds.Left + TEXTSTART;
			
			int y = bounds.Top + 2;
			if (enabled) {
				// normal draw
				Color color  = (selected && !toplevel) ? Color.White : SystemColors.MenuText;
				g.DrawString(text, SystemInformation.MenuFont, new SolidBrush(color), x, y, stringformat);
				g.DrawString(shortcut, SystemInformation.MenuFont, new SolidBrush(color), bounds.Left + 130, bounds.Top + 2, stringformat);
			} else {
				// disabled menuitem draw
				if (!selected) {
					g.DrawString(text, SystemInformation.MenuFont, SystemBrushes.ControlLightLight, x + 1, y + 1, stringformat);
					g.DrawString(shortcut, SystemInformation.MenuFont, SystemBrushes.ControlLightLight, bounds.Left + 130 + 1, bounds.Top + 2 + 1, stringformat);
				}
				g.DrawString(text, SystemInformation.MenuFont, new SolidBrush(SystemColors.GrayText), x, y, stringformat);
				g.DrawString(shortcut, SystemInformation.MenuFont, new SolidBrush(SystemColors.GrayText), bounds.Left + 130, bounds.Top + 2, stringformat);
			}
		}
	}
	
	public class VSNetStyle : MenuItemStyleDrawer
	{
		static Color bgcolor  = Color.FromArgb(246, 246, 246);
		static Color ibgcolor = Color.FromArgb(202, 202, 202);
		static Color sbcolor  = Color.FromArgb(173, 173, 209);
		static Color sbbcolor = Color.FromArgb(  0,   0, 128);
		
		static int TEXTSTART = 20;
		
		public void DrawCheckmark(Graphics g, Rectangle bounds, bool selected)
		{
			ControlPaint.DrawMenuGlyph(g, new Rectangle(bounds.X + 2, bounds.Y + 2, 14, 14), MenuGlyph.Checkmark);
		}
		
		public void DrawIcon(Graphics g, Image icon, Rectangle bounds, bool selected, bool enabled, bool ischecked)
		{
	    	if (enabled) {
	    		if (selected) {
	    			ControlPaint.DrawImageDisabled(g, icon, bounds.Left + 2, bounds.Top + 2, Color.Black);
					g.DrawImage(icon, bounds.Left + 1, bounds.Top + 1);
	    		} else {
					g.DrawImage(icon, bounds.Left + 2, bounds.Top + 2);
	    		}
	    	} else
		    	ControlPaint.DrawImageDisabled(g, icon, bounds.Left + 2, bounds.Top + 2, SystemColors.HighlightText);
		}
		
		public void DrawSeparator(Graphics g, Rectangle bounds)
		{
			int y = bounds.Y + bounds.Height / 2;
			g.DrawLine(new Pen(SystemColors.ControlDark), bounds.X + SystemInformation.SmallIconSize.Width + 7, y, bounds.X + bounds.Width - 2, y);
		}
		
		public void DrawBackground(Graphics g, Rectangle bounds, DrawItemState state, bool toplevel, bool hasicon)
		{
			bool selected = (state & DrawItemState.Selected) > 0;
			
			if (selected || ((state & DrawItemState.HotLight) > 0)) {
				if (toplevel && selected) { // draw toplevel, selected menuitem
		    		g.FillRectangle(new SolidBrush(ibgcolor), bounds);
			    	ControlPaint.DrawBorder3D(g, bounds.Left, bounds.Top, bounds.Width, bounds.Height, Border3DStyle.Flat, Border3DSide.Top | Border3DSide.Left | Border3DSide.Right);
				} else { // draw menuitem, selected OR toplevel, hotlighted
		    		g.FillRectangle(new SolidBrush(sbcolor), bounds);
					g.DrawRectangle(new Pen(sbbcolor), bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1);
				}
			} else {
				if (!toplevel) { // draw menuitem, unselected
		    		g.FillRectangle(new SolidBrush(ibgcolor), bounds);
					bounds.X += SystemInformation.SmallIconSize.Width + 5;
					bounds.Width -= SystemInformation.SmallIconSize.Width + 5;
		    		g.FillRectangle(new SolidBrush(bgcolor), bounds);
				} else {
					// draw toplevel, unselected menuitem
					g.FillRectangle(SystemBrushes.Menu, bounds);
				}
			}
		}
		
		public void DrawMenuText(Graphics g, Rectangle bounds, string text, string shortcut, bool enabled, bool toplevel, DrawItemState state)
		{
		    StringFormat stringformat = new StringFormat();
			stringformat.HotkeyPrefix = ((state & DrawItemState.NoAccelerator) > 0) ? HotkeyPrefix.Hide : HotkeyPrefix.Show;
			int textwidth = (int)(g.MeasureString(text, SystemInformation.MenuFont).Width);
			
			int x = toplevel ? bounds.Left + (bounds.Width - textwidth) / 2: bounds.Left + TEXTSTART;
			int y = bounds.Top + 2;
			Brush brush = null;
			if (!enabled)
				brush = new SolidBrush(Color.FromArgb(120, SystemColors.MenuText));
			else
				brush = new SolidBrush(Color.Black);
			g.DrawString(text, SystemInformation.MenuFont, brush, x, y, stringformat);
			g.DrawString(shortcut, SystemInformation.MenuFont, brush, bounds.Left + 130, bounds.Top + 2, stringformat);
		}
	}
	
	public class RichMenuItem : MenuItem
	{
		string       shortcuttext = "";
	    StringFormat stringformat = new StringFormat();
		Bitmap       icon   = null;
		
		MenuItemStyleDrawer style = null;
		IconMenuStyle       menustyle   = IconMenuStyle.VSNet;
		
		public IconMenuStyle MenuStyle {
			get {
				return menustyle;
			}
			set {
				switch (value) {
					case IconMenuStyle.Office2000:
						style = new Office2000Style();
						OwnerDraw = true;
						break;
					case IconMenuStyle.VSNet:
						style = new VSNetStyle();
						OwnerDraw = true;
						break;
					default:
						style = null;
						OwnerDraw = false;
						break;
				}
			}
		}
		
		public string ShortcutText {
			get {
				return shortcuttext;
			}
			set {
				shortcuttext = value;
			}
		}
		
		public Bitmap Icon {
			get {
				return icon;
			}
			set {
				icon = value;
			}
		}
		public RichMenuItem()
		{
		}
		
		public RichMenuItem(IconMenuStyle style, string name, EventHandler handler, Shortcut shortcut) : this(style, name, handler)
		{
			this.Shortcut = shortcut;
		}
		
		public RichMenuItem(IconMenuStyle style, string name, EventHandler handler) : base(name, handler)
		{
			MenuStyle = style;
		}
		
//		public override MenuItem CloneMenu()
//		{
//			return (MenuItem)MemberwiseClone();
//		}
		
		protected override void OnMeasureItem(MeasureItemEventArgs e)
		{
			base.OnMeasureItem(e);
			
			// make shortcut text
			if (Shortcut != Shortcut.None) {
				string text = "";
				int    key  = (int)Shortcut;
				int    ch   = key & 0xFF;
				if (((int)Keys.Control & key) > 0)
					text += "Ctrl+";
				if (((int)Keys.Shift & key) > 0)
					text += "Shift+";
				if (((int)Keys.Alt & key) > 0)
					text += "Alt+";
				
				if (ch >= (int)Shortcut.F1 && ch <= (int)Shortcut.F12)
					text += "F" + (ch - (int)Shortcut.F1 + 1);
				else
					text += (char)ch;
				shortcuttext = text;
			} 
			
			if (menustyle != IconMenuStyle.Standard) {
				if (Text == "-") {
					e.ItemHeight = 8;
					e.ItemWidth  = 4;
					return;
				}
				int textwidth = (int)(e.Graphics.MeasureString(Text + shortcuttext, SystemInformation.MenuFont).Width);
			    e.ItemHeight  = SystemInformation.MenuHeight;
			    if (Parent == Parent.GetMainMenu())
			    	e.ItemWidth  = textwidth - 5; // 5 is a magic number :)
				else
					e.ItemWidth   = Math.Max(160, textwidth + 50);
			}
		}
		
		protected override void OnSelect(EventArgs e)
		{
			base.OnSelect(e);
		}
		
		
		protected override void OnDrawItem(DrawItemEventArgs e)
		{
			base.OnDrawItem(e);
			Graphics  g      = e.Graphics;
			Rectangle bounds = e.Bounds;
			bool selected = (e.State & DrawItemState.Selected) > 0;
			bool toplevel = (Parent == Parent.GetMainMenu());
			bool hasicon  = Icon != null;
			
			style.DrawBackground(g, bounds, e.State, toplevel, hasicon);
			if (hasicon)
				style.DrawIcon(g, Icon, bounds, selected, Enabled, Checked);
			else
			if (Checked)
				style.DrawCheckmark(g, bounds, selected);
			
			if (Text == "-") {
				style.DrawSeparator(g, bounds);
			} else {
				style.DrawMenuText(g, bounds, Text, shortcuttext, Enabled, toplevel, e.State);
			}
		}
	}	
}

⌨️ 快捷键说明

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