Sfoglia il codice sorgente

collection completion, drawing issues, missing features

svn path=/trunk/mcs/; revision=35644
Jordi Mas i Hernandez 21 anni fa
parent
commit
7f63ddfb20

+ 5 - 1
mcs/class/Managed.Windows.Forms/System.Windows.Forms/Form.cs

@@ -23,9 +23,12 @@
 //	Peter Bartok	[email protected]
 //
 //
-// $Revision: 1.20 $
+// $Revision: 1.21 $
 // $Modtime: $
 // $Log: Form.cs,v $
+// Revision 1.21  2004/11/04 14:47:58  jordi
+// collection completion, drawing issues, missing features
+//
 // Revision 1.20  2004/10/29 15:55:26  jordi
 // Menu key navigation, itemcollection completion, menu fixes
 //
@@ -214,6 +217,7 @@ namespace System.Windows.Forms {
 					int menu_height;
 
 					menu_height = MenuAPI.MenuBarCalcSize(DeviceContext, owner.Menu.menu_handle, ClientSize.Width);
+					Invalidate (new Rectangle (0, 0, ClientSize.Width, menu_height));					
 					owner.SetBoundsCore(0, menu_height, ClientSize.Width, ClientSize.Height-menu_height, BoundsSpecified.All);
 				}
 			}

+ 6 - 4
mcs/class/Managed.Windows.Forms/System.Windows.Forms/MainMenu.cs

@@ -54,9 +54,11 @@ namespace System.Windows.Forms
 
 		#region Public Methods
 			
-		public virtual MainMenu CloneMenu()
+		public virtual MainMenu CloneMenu ()
 		{
-			throw new NotImplementedException ();
+			MainMenu new_menu = new MainMenu ();
+			new_menu.CloneMenu (this);
+			return new_menu;
 		}
 		
 		protected override IntPtr CreateMenuHandle ()
@@ -66,7 +68,7 @@ namespace System.Windows.Forms
 
 		protected void Dispose (bool disposing)
 		{
-			throw new NotImplementedException ();
+			base.Dispose (disposing);
 		}
 
 		public Form GetForm ()
@@ -96,7 +98,7 @@ namespace System.Windows.Forms
 		}
 		
 		internal void OnMouseMove (Form window, MouseEventArgs e)
-		{
+		{			
 			MenuAPI.TrackBarMouseEvent (Handle, window, e, MenuAPI.MenuMouseEvent.Move);
 		}
 		

+ 119 - 42
mcs/class/Managed.Windows.Forms/System.Windows.Forms/Menu.cs

@@ -22,8 +22,11 @@
 // Authors:
 //	Jordi Mas i Hernandez, [email protected]
 //
+//	TODO:
+//		- Merge menus
+//		- MDI integration
+//		- ShortCut navigation
 //
-
 // NOT COMPLETE
 
 using System.Collections;
@@ -35,10 +38,12 @@ namespace System.Windows.Forms
 	{
 		internal MenuItemCollection menu_items;
 		internal IntPtr menu_handle = IntPtr.Zero;
+		internal bool is_dirty = true;
+		internal bool creating = false;
 
 		public const int FindHandle = 0;
 		public const int FindShortcut = 1;
-		
+
  		protected Menu (MenuItem[] items)
 		{
 			menu_items = new MenuItemCollection (this);
@@ -51,15 +56,21 @@ namespace System.Windows.Forms
 		#region Public Properties
 		public IntPtr Handle {
 			get {
+				if (is_dirty && creating == false) {
+					Dispose (true);
+				}
+
 				if (menu_handle == IntPtr.Zero) {
+					Console.WriteLine ("Create Handle");
 					menu_handle = CreateMenuHandle ();
 					CreateItems ();
+					is_dirty = false;
 				}
 
 				return menu_handle;
 			}
 		}
-		
+
 		public virtual bool IsParent {
 			get {
 				if (menu_items != null && menu_items.Count > 0)
@@ -68,31 +79,45 @@ namespace System.Windows.Forms
 					return false;
 			}
 		}
-		
+
 		public MenuItem MdiListItem {
 			get {
 				throw new NotImplementedException ();
 			}
 		}
-		
+
 		public MenuItemCollection MenuItems {
 			get { return menu_items; }
 		}
 
 		#endregion Public Properties
 
+		#region Private Properties
+
+		internal bool IsDirty {
+			get { return is_dirty; }
+			set { is_dirty = value; }
+		}
+
+		#endregion Private Properties
+
 		#region Public Methods
-			
+
 		protected void CloneMenu (Menu menuSrc)
 		{
-			throw new NotImplementedException ();
+			Dispose (true);
+
+			menu_items = new MenuItemCollection (this);
+
+			for (int i = 0; i < menuSrc.MenuItems.Count ; i++)
+				menu_items.Add (menuSrc.MenuItems [i]);
 		}
-		
+
 		protected virtual IntPtr CreateMenuHandle ()
 		{
 			IntPtr menu;
-			menu  = MenuAPI.CreatePopupMenu ();
-			Console.WriteLine ("Menu.CreateMenuHandle:" + menu);
+
+			menu = MenuAPI.CreatePopupMenu ();
 			return menu;
 		}
 
@@ -101,9 +126,10 @@ namespace System.Windows.Forms
 			if (disposing) {
 				if (menu_handle != IntPtr.Zero)
 					MenuAPI.DestroyMenu (menu_handle);
+					menu_handle = IntPtr.Zero;
 			}
 		}
-		
+
 		public MenuItem FindMenuItem (int type, IntPtr value)
 		{
 			throw new NotImplementedException ();
@@ -113,34 +139,38 @@ namespace System.Windows.Forms
 		{
 			throw new NotImplementedException ();
 		}
-		
+
 		public ContextMenu GetContextMenu ()
 		{
-			throw new NotImplementedException ();
+			if (this is ContextMenu)
+				return (ContextMenu) this;
+			else
+				return null;
 		}
-		
+
 		public MainMenu GetMainMenu ()
 		{
 			if (this is MainMenu)
 				return (MainMenu) this;
-			else 
+			else
 				return null;
 		}
-		
+
 		public virtual void MergeMenu (Menu menuSrc)
 		{
-			throw new NotImplementedException ();
+			if (menuSrc == this)
+				throw new ArgumentException ("The menu cannot be merged with itself");
+
 		}
 
 		protected internal virtual bool ProcessCmdKey (ref Message msg, Keys keyData)
 		{
-			return false;			
+			return false;
 		}
 
 		public override string ToString ()
-		{			
+		{
 			return base.ToString ();
-						
 		}
 
 		#endregion Public Methods
@@ -149,13 +179,12 @@ namespace System.Windows.Forms
 
 		protected void CreateItems ()
 		{
-			Console.WriteLine ("Menu.CreateItems:" + menu_items.Count);
+			creating = true;
 
-			for (int i = 0; i < menu_items.Count; i++) 
+			for (int i = 0; i < menu_items.Count; i++)
 				menu_items[i].Create ();
-				
-			Console.WriteLine ("End Menu.CreateItems:" + menu_items.Count);
 
+			creating = false;
 		}
 
 		#endregion Private Methods
@@ -164,7 +193,7 @@ namespace System.Windows.Forms
 		{
 			private Menu owner;
 			private ArrayList items = new ArrayList ();
-			
+
 			public MenuItemCollection (Menu owner)
 			{
 				this.owner = owner;
@@ -193,12 +222,17 @@ namespace System.Windows.Forms
 			}
 
 			public MenuItem this [int index] {
-				get { return (MenuItem) items[index]; }
+				get {
+					if (index < 0 || index >= Count)
+						throw new ArgumentOutOfRangeException ("Index of out range");
+
+					return (MenuItem) items[index];
+				}
 			}
 
 			object IList.this[int index] {
 				get { return items[index]; }
-				set { items[index] = value; }
+				set { throw new NotSupportedException (); }
 			}
 
 			#endregion Public Properties
@@ -208,29 +242,56 @@ namespace System.Windows.Forms
 			public virtual int Add (MenuItem mi)
 			{
 				mi.parent_menu = owner;
+				mi.Index = items.Count;
 				items.Add (mi);
-				
+
+				owner.IsDirty = true;
 				return items.Count - 1;
 			}
 
 			public virtual MenuItem Add (string s)
 			{
-				throw new NotImplementedException ();
+				MenuItem item = new MenuItem (s);
+				Add (item);
+				return item;
 			}
 
 			public virtual int Add (int index, MenuItem mi)
 			{
-				throw new NotImplementedException ();
+				if (index < 0 || index >= Count)
+					throw new ArgumentOutOfRangeException ("Index of out range");
+
+				ArrayList new_items = new ArrayList (Count + 1);
+
+				for (int i = 0; i < index; i++)
+					new_items.Add (items[i]);
+
+				new_items.Add (mi);
+
+				for (int i = index; i < Count; i++)
+					new_items.Add (items[i]);
+
+				items = new_items;
+				UpdateItemsIndices ();
+				owner.IsDirty = true;
+
+				return index;
 			}
 
 			public virtual MenuItem Add (string s, EventHandler e)
 			{
-				throw new NotImplementedException ();
+				MenuItem item = new MenuItem (s, e);
+				Add (item);
+
+				return item;
 			}
 
 			public virtual MenuItem Add (string s, MenuItem[] items)
 			{
-				throw new NotImplementedException ();
+				MenuItem item = new MenuItem (s, items);
+				Add (item);
+
+				return item;
 			}
 
 			public virtual void AddRange (MenuItem[] items)
@@ -240,29 +301,29 @@ namespace System.Windows.Forms
 
 				foreach (MenuItem mi in items)
 					Add (mi);
-
 			}
 
 			public virtual void Clear ()
 			{
 				items.Clear ();
+				owner.IsDirty = true;
 			}
 
 			public bool Contains (MenuItem value)
 			{
 				return items.Contains (value);
 			}
-			
+
 			public virtual void CopyTo (Array dest, int index)
 			{
-				throw new NotImplementedException ();	
+				items.CopyTo (dest, index);
 			}
-			
+
 			public virtual IEnumerator GetEnumerator ()
 			{
 				return items.GetEnumerator ();
 			}
-			
+
 			int IList.Add (object value)
 			{
 				return Add ((MenuItem)value);
@@ -280,12 +341,12 @@ namespace System.Windows.Forms
 
 			void IList.Insert (int index, object value)
 			{
-				throw new NotImplementedException ();
+				Add (index, (MenuItem) value);
 			}
 
 			void IList.Remove (object value)
 			{
-				throw new NotImplementedException ();
+				Remove ((MenuItem) value);
 			}
 
 			public int IndexOf (MenuItem value)
@@ -295,15 +356,31 @@ namespace System.Windows.Forms
 
 			public virtual void Remove (MenuItem item)
 			{
-				throw new NotImplementedException ();
+				RemoveAt (item.Index);
 			}
-			
+
 			public virtual void RemoveAt (int index)
 			{
-				throw new NotImplementedException ();
+				if (index < 0 || index >= Count)
+					throw new ArgumentOutOfRangeException ("Index of out range");
+
+				items.RemoveAt (index);
+
+				UpdateItemsIndices ();
+				owner.IsDirty = true;
 			}
 
 			#endregion Public Methods
+
+			#region Private Methods
+
+			private void UpdateItemsIndices ()
+			{
+				for (int i = 0; i < Count; i++)	// Recalculate indeces
+					((MenuItem)items[i]).Index = i;
+			}
+
+			#endregion Private Methods
 		}
 	}
 }

+ 64 - 69
mcs/class/Managed.Windows.Forms/System.Windows.Forms/MenuAPI.cs

@@ -34,6 +34,9 @@ namespace System.Windows.Forms
 
 	/*
 		This class mimics the Win32 API Menu functionality
+		
+		When writting this code the Wine project was of great help to
+		understand the logic behind some Win32 issues. Thanks to them. Jordi,		
 	*/
 	internal class MenuAPI
 	{
@@ -53,7 +56,7 @@ namespace System.Windows.Forms
     		const int SM_CYARROWCHECK = 16;		// Height of the arrow
     		const int SM_CYMENU = 18;		// Minimum height of a menu
     		const int MENU_TAB_SPACE = 8;		// Pixels added to the width of an item because of a tab
-    		const int MENU_BAR_ITEMS_SPACE = 12;	// Space between menu bar items
+    		const int MENU_BAR_ITEMS_SPACE = 8;	// Space between menu bar items
 
 		public class MENU
 		{
@@ -114,17 +117,7 @@ namespace System.Windows.Forms
 				hCurrentMenu = hTopMenu = IntPtr.Zero;
 			}
 		};
-
-		static void DumpMenuItems (ArrayList list)
-		{
-			Console.WriteLine ("Menu items dump start--- ");
-
-			for (int i = 0; i < list.Count; i++)
-				Console.WriteLine ("idx:{0} {1} {2}", i, ((MENUITEM)list[i]).item, ((MENUITEM)list[i]).item.Separator);
-
-			Console.WriteLine ("Menu items dump end --- ");
-		}
-
+		
 		public enum MenuMouseEvent
 		{
 			Down,
@@ -136,7 +129,7 @@ namespace System.Windows.Forms
 			First,
 			Last,
 			Next,
-			Previous
+			Previous,
 		}
 
 		internal enum MF
@@ -170,8 +163,7 @@ namespace System.Windows.Forms
 		}
 
 		static MenuAPI ()
-		{
-			Console.WriteLine ("MenuAPI::MenuAPI");
+		{			
 			string_format_text.LineAlignment = StringAlignment.Center;
 			string_format_text.Alignment = StringAlignment.Near;
 			string_format_text.HotkeyPrefix = HotkeyPrefix.Show;
@@ -187,8 +179,7 @@ namespace System.Windows.Forms
 
 		static public IntPtr StoreMenuID (MENU menu)
 		{
-			int id = menu_list.Add (menu);
-			//Console.WriteLine ("StoreMenuID:" + id + 1);
+			int id = menu_list.Add (menu);			
 			return (IntPtr)(id + 1);
 		}
 
@@ -207,9 +198,7 @@ namespace System.Windows.Forms
 		}
 
 		static public IntPtr CreatePopupMenu ()
-		{
-			Console.WriteLine ("MenuAPI.CreatePopupMenu");
-
+		{			
 			MENU popMenu = new MENU ();
 			popMenu.Flags |= MF.MF_POPUP;
 			return StoreMenuID (popMenu);
@@ -246,9 +235,7 @@ namespace System.Windows.Forms
 			id = menu.items.Count;
 			menu_item.pos = menu.items.Count;
 			menu.items.Insert (uItem, menu_item);
-
-			//Console.WriteLine ("InsertMenuItem {0} {1} {2}" + menu.items.Count,
-			//);
+			
 			return id;
 		}
 
@@ -294,13 +281,13 @@ namespace System.Windows.Forms
 				item.rect.Height = SEPARATOR_HEIGHT / 2;
 				item.rect.Width = -1;
 				return;
-			}
-
+			}			
+			
 			SizeF size;
 			size =  dc.MeasureString (item.item.Text, MENU_FONT);
 			item.rect.Width = (int) size.Width;
-			item.rect.Height = (int) size.Height;
-
+			item.rect.Height = (int) size.Height;						
+			
 			if (!menuBar) {
 
 				if (item.item.Shortcut != Shortcut.None && item.item.ShowShortcut) {
@@ -312,7 +299,7 @@ namespace System.Windows.Forms
 				item.rect.Width += 4 + (SM_CXMENUCHECK * 2);
 			}
 			else {
-				//item.rect.Width += MENU_BAR_ITEMS_SPACE;
+				item.rect.Width += MENU_BAR_ITEMS_SPACE;
 				x += item.rect.Width;
 			}
 
@@ -403,7 +390,7 @@ namespace System.Windows.Forms
 			if (item.item.BarBreak) { /* Draw vertical break bar*/
 
 				Rectangle rect = item.rect;
-				rect.Y++;
+				rect.Y++;				
 	        		rect.Width = 3;
 	        		rect.Height = menu_height - 6;
 
@@ -415,12 +402,16 @@ namespace System.Windows.Forms
 
 			}
 
-			//Console.WriteLine ("!{0}, {1}, {2}", item.item.Text, item.rect, rect_text);
+			//Console.WriteLine ("DrawMenuItem {0}, {1}, {2}", item.item.Text, item.rect, rect_text);
 
 			if ((item.fState & MF.MF_HILITE) == MF.MF_HILITE) {
+				Rectangle rect = item.rect;
+				rect.X++;
+				rect.Width -=2;
+				
 				dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush
-					(ThemeEngine.Current.ColorHilight), item.rect);
-			}
+					(ThemeEngine.Current.ColorHilight), rect);
+			}			
 
 			if (item.item.Enabled) {
 
@@ -477,13 +468,13 @@ namespace System.Windows.Forms
 				Graphics gr = Graphics.FromImage (bmp);
 				Rectangle rect_arrow = new Rectangle (0, 0, SM_CXMENUCHECK, SM_CYMENUCHECK);
 
-				if (item.item.RadioCheck)
-					ControlPaint.DrawMenuGlyph (gr, rect_arrow, MenuGlyph.Bullet);
-				else
-					ControlPaint.DrawMenuGlyph (gr, rect_arrow, MenuGlyph.Checkmark);
+				if (item.item.RadioCheck) 
+					ControlPaint.DrawMenuGlyph (gr, rect_arrow, MenuGlyph.Bullet);				
+				else 
+					ControlPaint.DrawMenuGlyph (gr, rect_arrow, MenuGlyph.Checkmark);				
 
-				bmp.MakeTransparent ();
-				dc.DrawImage (bmp, area.X, item.rect.Y + (item.rect.Height /2));
+				bmp.MakeTransparent ();					
+				dc.DrawImage (bmp, area.X, item.rect.Y + ((item.rect.Height - SM_CYMENUCHECK) / 2));
 
 				gr.Dispose ();
 				bmp.Dispose ();
@@ -529,22 +520,32 @@ namespace System.Windows.Forms
 		{
 			int x = 0;
 			int i = 0;
+			int y = 0;
 			MENU menu = GetMenuFromID (hMenu);
-			MENUITEM item;
+			menu.Height = 0;
+			MENUITEM item;			
 
 			while (i < menu.items.Count) {
 
 				item = (MENUITEM) menu.items[i];
-				CalcItemSize (dc, item, 0, x, true);
+				CalcItemSize (dc, item, y, x, true);
 				i = i + 1;
+				
+				if (x + item.rect.Width > width) {
+					item.rect.X = 0;					
+					y += item.rect.Height;
+					item.rect.Y = y;
+					x = 0;					
+				}
+				
 				x += item.rect.Width;
 				item.fState |= MF.MF_MENUBAR;
 
-				if (item.rect.Height > menu.Height)
-					menu.Height = item.rect.Height;
+				if (y + item.rect.Height > menu.Height)
+					menu.Height = item.rect.Height + y;
 			}
 
-			menu.Width = width;
+			menu.Width = width;			
 			return menu.Height;
 		}
 
@@ -556,12 +557,10 @@ namespace System.Windows.Forms
 
 			if (menu.Height == 0)
 				MenuBarCalcSize (dc, hMenu, rect_menu.Width);
-
+				
 			rect.Height = menu.Height;
-			rect.Width = menu.Width;
-
-			Console.WriteLine ("DrawMenuBar {0}", rect);
-
+			rect.Width = menu.Width;				
+			
 			for (int i = 0; i < menu.items.Count; i++)
 				DrawMenuItem (dc, (MENUITEM) menu.items[i], menu.Height, true);
 		}
@@ -575,22 +574,18 @@ namespace System.Windows.Forms
 
 			for (int i = 0; i < menu.items.Count; i++) {
 				MENUITEM item = (MENUITEM) menu.items[i];
-				if (item.rect.Contains (pt)) {
-					//Console.WriteLine ("FindItemByCoords: " + item.item.Text);
+				if (item.rect.Contains (pt)) {					
 					return item;
 				}
 			}
-
-			//Console.WriteLine ("FindItemByCoords none ");
+			
 			return null;
 		}
 
 		static public void SelectItem (IntPtr hMenu, MENUITEM item, bool execute)
 		{
 			MENU menu = GetMenuFromID (hMenu);
-			//int pos = 0;
-
-			//Console.WriteLine ("Current: {0} select {1}", menu_parent.hCurrent, hMenu);
+			
 			MENUITEM highlight_item = null;
 
 			/* Already selected */
@@ -757,7 +752,6 @@ namespace System.Windows.Forms
 
 		static private void MenuBarMove (IntPtr hMenu, MENUITEM item)
 		{
-
 			MENU menu = GetMenuFromID (hMenu);
 			Point pnt = new Point (item.rect.X, item.rect.Y + item.rect.Height);
 			pnt = menu.Wnd.PointToScreen (pnt);
@@ -780,23 +774,20 @@ namespace System.Windows.Forms
 
 					MenuAPI.MENUITEM item = MenuAPI.FindItemByCoords (hMenu, new Point (e.X, e.Y));
 
-					//Console.WriteLine ("menubar: {0} {1}",item.rect.X,
-					//	item.rect.Y + item.rect.Height + 1);
-
 					if (item != null && menu.SelectedItem != item)
 						MenuBarMove (hMenu, item);
 
 					break;
 				}
 
-				case MenuMouseEvent.Move: {
+				case MenuMouseEvent.Move: {					
 
-					if (menu.tracker.hCurrentMenu != IntPtr.Zero) {
-
-						MenuAPI.MENUITEM item = MenuAPI.FindItemByCoords (hMenu, new Point (e.X, e.Y));
+					if (menu.tracker.hCurrentMenu != IntPtr.Zero) {					
 
+						MenuAPI.MENUITEM item = MenuAPI.FindItemByCoords (hMenu, new Point (e.X, e.Y));						
+						
 						if (item != null && menu.SelectedItem != item)
-						MenuBarMove (hMenu, item);
+							MenuBarMove (hMenu, item);
 					}
 					break;
 				}
@@ -1119,11 +1110,15 @@ namespace System.Windows.Forms
 			if (item != null) {
 				MenuAPI.SelectItem (hMenu, item, true);
 			} else {
-
-				if (menu.bMenubar) {
-					//Console.WriteLine ("MenuBar tracker move " + e.Y);
-					//MenuAPI.TrackBarMouseEvent (tracker.hTopMenu,
-					//	this, e, MenuAPI.MenuMouseEvent.Move);
+				
+				MenuAPI.MENU menu_parent = null;
+				
+				if (menu.tracker.hTopMenu != IntPtr.Zero)
+					menu_parent = MenuAPI.GetMenuFromID (menu.tracker.hTopMenu);
+
+				if (menu_parent!=null && menu_parent.bMenubar) {
+					
+					Console.WriteLine ("MenuBar tracker move " + e.Y );
 
 					Point pnt = PointToClient (MousePosition);
 

+ 190 - 184
mcs/class/Managed.Windows.Forms/System.Windows.Forms/MenuItem.cs

@@ -49,9 +49,12 @@ namespace System.Windows.Forms
 		private bool defaut_item;
 		private bool visible;
 		private bool ownerdraw;
+		private int menuid;
+		private int mergeorder;
+		private MenuMerge mergetype;
 
 		public MenuItem (): base (null)
-		{
+		{	
 			CommonConstructor (string.Empty);
 			shortcut = Shortcut.None;
 		}
@@ -62,10 +65,11 @@ namespace System.Windows.Forms
 			shortcut = Shortcut.None;
 		}
 
-		public MenuItem (string text, EventHandler e) : base (null)
+		public MenuItem (string text, EventHandler onClick) : base (null)
 		{
 			CommonConstructor (text);
 			shortcut = Shortcut.None;
+			Click += onClick;
 		}
 
 		public MenuItem (string text, MenuItem[] items) : base (items)
@@ -87,6 +91,9 @@ namespace System.Windows.Forms
 		{
 			CommonConstructor (text);
 			shortcut = shortcut;
+			mergeorder = mergeOrder;
+			mergetype = mergeType;
+
 			Click += onClick;
 			Popup += onPopup;
 			Select += onSelect;
@@ -105,15 +112,17 @@ namespace System.Windows.Forms
 			ownerdraw = false;
 			index = -1;
 			mnemonic = '\0';
-
+			menuid = -1;
+			mergeorder = 0;
+			mergetype = MenuMerge.Add;
 			Text = text;	// Text can change separator status
 		}
 
-		#region Events		
-		public event EventHandler Click;		
-		public event DrawItemEventHandler DrawItem;			
+		#region Events
+		public event EventHandler Click;
+		public event DrawItemEventHandler DrawItem;
 		public event MeasureItemEventHandler MeasureItem;
-		public event EventHandler Popup;		
+		public event EventHandler Popup;
 		public event EventHandler Select;
 		#endregion // Events
 
@@ -123,91 +132,78 @@ namespace System.Windows.Forms
 			get { return break_; }
 			set { break_ = value; }
 		}
-		
+
 		public bool Break {
 			get { return bar_break; }
-			set { bar_break = value; } 
+			set { bar_break = value; }
 		}
-		
+
 		public bool Checked {
 			get { return checked_; }
-			set { checked_ = value; } 
-		}		
-		
+			set { checked_ = value; }
+		}
+
 		public bool DefaultItem {
 			get { return defaut_item; }
-			set { defaut_item = value; } 
+			set { defaut_item = value; }
 		}
-		
+
 		public bool Enabled {
 			get { return enabled; }
-			set { enabled = value; } 
-		}		
-		
+			set { enabled = value; }
+		}
+
 		public int Index {
 			get { return index; }
-			set { index = value; } 
+			set { index = value; }
 		}
-		
+
 		public override bool IsParent {
-			get {
-				return IsPopup;
-			}		
+			get { return IsPopup; }
 		}
 
 		public bool MdiList {
 			get { return mdilist; }
-			set { mdilist = value; } 
+			set { mdilist = value; }
 		}
-		
-		
+
 		protected int MenuID {
-			get {
-				throw new NotImplementedException ();
-			}
-			set{
-				throw new NotImplementedException ();
-			}
+			get { return menuid; }
 		}
-		
-		public int MergeOrder{
-			get {
-				throw new NotImplementedException ();
-			}
-			set{
-				throw new NotImplementedException ();
-			}
+
+		public int MergeOrder {
+			get { return mergeorder; }
+			set { mergeorder = value; }
 		}
-		
+
 		public MenuMerge MergeType {
-			get {
-				throw new NotImplementedException ();
-			}
-			set{
-				throw new NotImplementedException ();
+			get { return mergetype;	}
+			set {
+				if (!Enum.IsDefined (typeof (MenuMerge), value))
+					throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for MenuMerge", value));
+
+				mergetype = value;
 			}
 		}
-		
+
 		public char Mnemonic {
-			get { return mnemonic; }			
+			get { return mnemonic; }
 		}
-		
+
 		public bool OwnerDraw {
-			get { return ownerdraw; }			
-			set{				
-				throw new NotImplementedException ();
-			}
+			get { return ownerdraw; }
+			set { ownerdraw = value; }
 		}
-		
+
 		public Menu Parent {
 			get { return parent_menu;}
 		}
-		
+
 		public bool RadioCheck {
 			get { return radiocheck; }
-			set { radiocheck = value; } 
+			set { radiocheck = value; }
 		}
-		
+
 		public Shortcut Shortcut {
 			get { return shortcut;}
 			set {
@@ -217,12 +213,12 @@ namespace System.Windows.Forms
 				shortcut = value;
 			}
 		}
-		
+
 		public bool ShowShortcut {
 			get { return showshortcut;}
 			set { showshortcut = value; }
-		}		
-		
+		}
+
 		public string Text {
 			get { return text; }
 			set {
@@ -233,11 +229,10 @@ namespace System.Windows.Forms
 				else
 					separator = false;
 
-				ProcessMnemonic ();	
-
+				ProcessMnemonic ();
 			}
 		}
-		
+
 		public bool Visible {
 			get { return visible;}
 			set { visible = value; }
@@ -253,7 +248,7 @@ namespace System.Windows.Forms
 					return true;
 				else
 					return false;
-			}			
+			}
 		}
 
 		internal bool Separator {
@@ -267,27 +262,52 @@ namespace System.Windows.Forms
 
 		public virtual MenuItem CloneMenu ()
 		{
-			throw new NotImplementedException ();
+			MenuItem item = new MenuItem ();
+			item.CloneMenu (item);
+			return item;
 		}
-		
+
 		protected void CloneMenu (MenuItem menuitem)
 		{
-			throw new NotImplementedException ();
+			base.CloneMenu (menuitem); // Copy subitems
+
+			// Properties
+			BarBreak = menuitem.BarBreak;
+			Break = menuitem.Break;
+			Checked = menuitem.Checked;
+			DefaultItem = menuitem.DefaultItem;
+			Enabled = menuitem.Enabled;			
+			MergeOrder = menuitem.MergeOrder;
+			MergeType = menuitem.MergeType;
+			OwnerDraw = menuitem.OwnerDraw;
+			//Parent = menuitem.Parent;
+			RadioCheck = menuitem.RadioCheck;
+			Shortcut = menuitem.Shortcut;
+			ShowShortcut = menuitem.ShowShortcut;
+			Text = menuitem.Text;
+			Visible = menuitem.Visible;
+
+			// Events
+			Click = menuitem.Click;
+			DrawItem = menuitem.DrawItem;
+			MeasureItem = menuitem.MeasureItem;
+			Popup = menuitem.Popup;
+			Select = menuitem.Select;
 		}
 
 		protected override void Dispose (bool disposing)
 		{
-			throw new NotImplementedException ();
+			// Nothing to dispose
 		}
-		
+
 		public virtual void MergeMenu ()
 		{
-			throw new NotImplementedException ();
-		}		
-		
+			base.MergeMenu (this);
+		}
+
 		public void MergeMenu (MenuItem menuitem)
 		{
-			throw new NotImplementedException ();
+			base.MergeMenu (menuitem);
 		}
 
 		protected virtual void OnClick (EventArgs e)
@@ -302,16 +322,16 @@ namespace System.Windows.Forms
 				DrawItem (this, e);
 		}
 
-		
+
 		protected virtual void OnInitMenuPopup (EventArgs e)
 		{
-
+			OnPopup (e);
 		}
 
 		protected virtual void OnMeasureItem (MeasureItemEventArgs e)
 		{
 			if (MeasureItem != null)
-				MeasureItem (this, e);			
+				MeasureItem (this, e);
 		}
 
 		protected virtual void OnPopup (EventArgs e)
@@ -325,7 +345,7 @@ namespace System.Windows.Forms
 			if (Select != null)
 				Select (this, e);
 		}
-		
+
 		public void PerformClick ()
 		{
 			OnClick (EventArgs.Empty);
@@ -335,7 +355,7 @@ namespace System.Windows.Forms
 		{
 			OnSelect (EventArgs.Empty);
 		}
-		
+
 		public override string ToString ()
 		{
 			return "item:" + text;
@@ -347,14 +367,11 @@ namespace System.Windows.Forms
 
 		internal void Create ()
 		{
-			IntPtr hSubMenu = IntPtr.Zero;			
+			IntPtr hSubMenu = IntPtr.Zero;
 
-			//Console.WriteLine ("MenuItem.Created:" + Text + " parent:" + Parent.menu_handle/* + " " +
-			//	Environment.StackTrace*/);
-			index = MenuAPI.InsertMenuItem (Parent.Handle, -1, true, this, ref hSubMenu);
+			menuid = index = MenuAPI.InsertMenuItem (Parent.Handle, -1, true, this, ref hSubMenu);
 
 			if (IsPopup) {
-				//Console.WriteLine ("MenuItem.Create Popup:" + hSubMenu);
 				menu_handle = hSubMenu;
 				CreateItems ();
 			}
@@ -383,117 +400,106 @@ namespace System.Windows.Forms
 
 			mnemonic = '\0';
 		}
-		
+
 		private string GetShortCutTextCtrl () { return "Ctrl"; }
+		private string GetShortCutTextAlt () { return "Alt"; }
+		private string GetShortCutTextShift () { return "Shift"; }		
 
 		internal string GetShortCutText ()
 		{
-			//TODO: Complete the table
-			switch (Shortcut)
-			{
-				case Shortcut.Ctrl0:
-					return GetShortCutTextCtrl () + "+0";
-				case Shortcut.Ctrl1:	
-					return GetShortCutTextCtrl () + "+1";
-				case Shortcut.Ctrl2:	
-					return GetShortCutTextCtrl () + "+2";
-				case Shortcut.Ctrl3:	
-					return GetShortCutTextCtrl () + "+3";
-				case Shortcut.Ctrl4:	
-					return GetShortCutTextCtrl () + "+4";
-				case Shortcut.Ctrl5:	
-					return GetShortCutTextCtrl () + "+5";
-				case Shortcut.Ctrl6:	
-					return GetShortCutTextCtrl () + "+6";
-				case Shortcut.Ctrl7:	
-					return GetShortCutTextCtrl () + "+7";
-				case Shortcut.Ctrl8:	
-					return GetShortCutTextCtrl () + "+8";
-				case Shortcut.Ctrl9:	
-					return GetShortCutTextCtrl () + "+9";
-				case Shortcut.CtrlA:	
-					return GetShortCutTextCtrl () + "+A";
-				case Shortcut.CtrlB:	
-					return GetShortCutTextCtrl () + "+B";
-				case Shortcut.CtrlC:	
-					return GetShortCutTextCtrl () + "+C";
-				case Shortcut.CtrlD:	
-					return GetShortCutTextCtrl () + "+D";
-				case Shortcut.CtrlDel:	
+			/* Ctrl+A - Ctrl+Z */
+			if (Shortcut >= Shortcut.CtrlA && Shortcut <= Shortcut.CtrlZ)
+				return GetShortCutTextCtrl () + "+" + (char)((int) 'A' + (int)(Shortcut - Shortcut.CtrlA));
+
+			/* Alt+0 - Alt+9 */
+			if (Shortcut >= Shortcut.Alt0 && Shortcut <= Shortcut.Alt9)
+				return GetShortCutTextAlt () + "+" + (char)((int) '0' + (int)(Shortcut - Shortcut.Alt0));
+
+			/* Alt+F1 - Alt+F2 */
+			if (Shortcut >= Shortcut.AltF1 && Shortcut <= Shortcut.AltF9)
+				return GetShortCutTextAlt () + "+F" + (char)((int) '1' + (int)(Shortcut - Shortcut.AltF1));
+
+			/* Ctrl+0 - Ctrl+9 */
+			if (Shortcut >= Shortcut.Ctrl0 && Shortcut <= Shortcut.Ctrl9)
+				return GetShortCutTextCtrl () + "+" + (char)((int) '0' + (int)(Shortcut - Shortcut.Ctrl0));
+							
+			/* Ctrl+F0 - Ctrl+F9 */
+			if (Shortcut >= Shortcut.CtrlF1 && Shortcut <= Shortcut.CtrlF9)
+				return GetShortCutTextCtrl () + "+F" + (char)((int) '1' + (int)(Shortcut - Shortcut.CtrlF1));
+				
+			/* Ctrl+Shift+0 - Ctrl+Shift+9 */
+			if (Shortcut >= Shortcut.CtrlShift0 && Shortcut <= Shortcut.CtrlShift9)
+				return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+" + (char)((int) '0' + (int)(Shortcut - Shortcut.CtrlShift0));
+				
+			/* Ctrl+Shift+A - Ctrl+Shift+Z */
+			if (Shortcut >= Shortcut.CtrlShiftA && Shortcut <= Shortcut.CtrlShiftZ)
+				return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+" + (char)((int) 'A' + (int)(Shortcut - Shortcut.CtrlShiftA));
+
+			/* Ctrl+Shift+F1 - Ctrl+Shift+F9 */
+			if (Shortcut >= Shortcut.CtrlShiftF1 && Shortcut <= Shortcut.CtrlShiftF9)
+				return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+F" + (char)((int) '1' + (int)(Shortcut - Shortcut.CtrlShiftF1));
+				
+			/* F1 - F9 */
+			if (Shortcut >= Shortcut.F1 && Shortcut <= Shortcut.F9)
+				return "F" + (char)((int) '1' + (int)(Shortcut - Shortcut.F1));
+				
+			/* Shift+F1 - Shift+F9 */
+			if (Shortcut >= Shortcut.ShiftF1 && Shortcut <= Shortcut.ShiftF9)
+				return GetShortCutTextShift () + "+F" + (char)((int) '1' + (int)(Shortcut - Shortcut.ShiftF1));
+			
+			/* Special cases */
+			switch (Shortcut) {
+				case Shortcut.AltBksp:
+					return "AltBksp";
+				case Shortcut.AltF10:
+					return GetShortCutTextAlt () + "+F10";
+				case Shortcut.AltF11:
+					return GetShortCutTextAlt () + "+F11";
+				case Shortcut.AltF12:
+					return GetShortCutTextAlt () + "+F12";
+				case Shortcut.CtrlDel:		
 					return GetShortCutTextCtrl () + "+Del";
-				case Shortcut.CtrlE:	
-					return GetShortCutTextCtrl () + "+E";
-				case Shortcut.CtrlF:	
-					return GetShortCutTextCtrl () + "+F";
-				case Shortcut.CtrlF1:	
-					return GetShortCutTextCtrl () + "+F1";
-				case Shortcut.CtrlF10:	
+				case Shortcut.CtrlF10:
 					return GetShortCutTextCtrl () + "+F10";
-				case Shortcut.CtrlF11:	
+				case Shortcut.CtrlF11:
 					return GetShortCutTextCtrl () + "+F11";
-				case Shortcut.CtrlF12:	
+				case Shortcut.CtrlF12:
 					return GetShortCutTextCtrl () + "+F12";
-				case Shortcut.CtrlF2:	
-					return GetShortCutTextCtrl () + "+F2";
-				case Shortcut.CtrlF3:	
-					return GetShortCutTextCtrl () + "+F3";
-				case Shortcut.CtrlF4:	
-					return GetShortCutTextCtrl () + "+F4";
-				case Shortcut.CtrlF5:	
-					return GetShortCutTextCtrl () + "+F5";
-				case Shortcut.CtrlF6:	
-					return GetShortCutTextCtrl () + "+F6";
-				case Shortcut.CtrlF7:	
-					return GetShortCutTextCtrl () + "+F7";
-				case Shortcut.CtrlF8:	
-					return GetShortCutTextCtrl () + "+F8";
-				case Shortcut.CtrlF9:	
-					return GetShortCutTextCtrl () + "+F9";
-				case Shortcut.CtrlG:	
-					return GetShortCutTextCtrl () + "+G";
-				case Shortcut.CtrlH:	
-					return GetShortCutTextCtrl () + "+H";
-				case Shortcut.CtrlI:	
-					return GetShortCutTextCtrl () + "+I";
-				case Shortcut.CtrlIns:	
+				case Shortcut.CtrlIns:
 					return GetShortCutTextCtrl () + "+Ins";
-				case Shortcut.CtrlJ:	
-					return GetShortCutTextCtrl () + "+J";
-				case Shortcut.CtrlK:	
-					return GetShortCutTextCtrl () + "+K";
-				case Shortcut.CtrlL:	
-					return GetShortCutTextCtrl () + "+L";
-				case Shortcut.CtrlM:	
-					return GetShortCutTextCtrl () + "+M";
-				case Shortcut.CtrlN:	
-					return GetShortCutTextCtrl () + "+N";
-				case Shortcut.CtrlO:	
-					return GetShortCutTextCtrl () + "+O";
-				case Shortcut.CtrlP:	
-					return GetShortCutTextCtrl () + "+P";
-				case Shortcut.CtrlQ:	
-					return GetShortCutTextCtrl () + "+Q";
-				case Shortcut.CtrlR:	
-					return GetShortCutTextCtrl () + "+R";
-				case Shortcut.CtrlS:
-					return GetShortCutTextCtrl () + "+S";									
-				case Shortcut.CtrlT:
-					return GetShortCutTextCtrl () + "+T";
-				case Shortcut.CtrlU:
-					return GetShortCutTextCtrl () + "+U";
-				case Shortcut.CtrlV:
-					return GetShortCutTextCtrl () + "+V";				
-				case Shortcut.CtrlW:
-					return GetShortCutTextCtrl () + "+W";
-				case Shortcut.CtrlX:
-					return GetShortCutTextCtrl () + "+X";				
-				case Shortcut.CtrlY:
-					return GetShortCutTextCtrl () + "+Y";				
-				case Shortcut.CtrlZ:
-					return GetShortCutTextCtrl () + "+Z";				
+				case Shortcut.CtrlShiftF10:
+					return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+F10";
+				case Shortcut.CtrlShiftF11:
+					return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+F11";
+				case Shortcut.CtrlShiftF12:
+					return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+F12";
+				case Shortcut.Del:
+					return "Del";
+				case Shortcut.F10:
+					return "F10";	
+				case Shortcut.F11:
+					return "F11";	
+				case Shortcut.F12:
+					return "F12";	
+				case Shortcut.Ins:
+					return "Ins";	
+				case Shortcut.None:
+					return "None";	
+				case Shortcut.ShiftDel:
+					return GetShortCutTextShift () + "+Del";
+				case Shortcut.ShiftF10:
+					return GetShortCutTextShift () + "+F10";
+				case Shortcut.ShiftF11:
+					return GetShortCutTextShift () + "+F11";
+				case Shortcut.ShiftF12:
+					return GetShortCutTextShift () + "+F12";				
+				case Shortcut.ShiftIns:
+					return GetShortCutTextShift () + "+Ins";
 				default:
-					return "";
-			}
+					break;
+				}
+				
+			return "";
 		}
 
 		#endregion Private Methods