protected virtual void OnItemClick(ActionMenuItem oItem) { if (ItemClick != null) ItemClick(oItem); }
		public void Show(int nX, int nY)
		{
			// Decide if we need layered windows
			m_bLayered = (m_bSupportsLayered);					

			CreateParams cp = new CreateParams();

			// Any old title will do as it will not be shown
			cp.Caption = "PureComponents.ActionMenu";

			RecalcLayout();

			// get the max screen size. if the nX + Width or nY + Height is bigger than the area, them move it elsewhere and recalculate the
			// position
			Screen oScreen = Screen.FromHandle(this.Handle);

			if (nX + m_oCurrentSize.Width > oScreen.Bounds.Width)
				nX = oScreen.Bounds.Width - m_oCurrentSize.Width;

			if (nY + m_oCurrentSize.Height > oScreen.Bounds.Height)
				nY = oScreen.Bounds.Height - m_oCurrentSize.Height;

			// set the position
			m_oScreenPos = new Point(nX, nY);

			Size winSize = m_oCurrentSize;
			Point screenPos = m_oScreenPos;
			
			// Define the screen position/size			
			cp.X = nX;
			cp.Y = nY;
			cp.Height = winSize.Height;
			cp.Width = winSize.Width;

			// As a top-level window it has no parent
			cp.Parent = IntPtr.Zero;
			
			// Appear as a top-level window
			cp.Style = unchecked((int)(uint)WindowStyles.WS_POPUP);
			
			// Set styles so that it does not have a caption bar and is above all other 
			// windows in the ZOrder, i.e. TOPMOST
			cp.ExStyle = (int)WindowExStyles.WS_EX_TOPMOST + 
				(int)WindowExStyles.WS_EX_TOOLWINDOW;

			// OS specific style
			if (m_bLayered)
			{
				// If not on NT then we are going to use alpha blending on the shadow border
				// and so we need to specify the layered window style so the OS can handle it
				cp.ExStyle += (int)WindowExStyles.WS_EX_LAYERED;
			}

			// Create the actual window
			if (this.Handle == IntPtr.Zero)
				this.CreateHandle(cp);

			// Remember the correct screen drawing details
			m_oCurrentSize = winSize;
			m_oCurrentPoint = screenPos;

			// Update the image for display
			if (m_bLayered)
				UpdateLayeredWindow();
				
			// Show the window without activating it (i.e. do not take focus)
			User32.ShowWindow(this.Handle, (short)ShowWindowStyles.SW_SHOWNOACTIVATE);	
		
			MSG msg = new MSG();

			bool _exitLoop = false;

//			POINT lastMousePoint;

			while(!_exitLoop)
			{
				// Suspend thread until a windows message has arrived
				if (User32.WaitMessage())
				{
					// Take a peek at the message details without removing from queue
					while(!_exitLoop && User32.PeekMessage(ref msg, 0, 0, 0, (int)PeekMessageFlags.PM_NOREMOVE))
					{
						// test if the mouse up is in the area of the menu
						int localWidth = m_oCurrentSize.Width - m_aPosition[0, (int)PaintItem.SW];
						int localHeight = m_oCurrentSize.Height - m_aPosition[0, (int)PaintItem.SH];						
						
						bool eatMessage = false;
						
						#region mouse move
						if (msg.message == (int)Msgs.WM_MOUSEMOVE)
						{
							POINT screenPosMsg = MousePositionToScreen(msg);
							
							// Is the POINT inside the Popup window rectangle
							if ((screenPosMsg.x >= m_oCurrentPoint.X) && (screenPosMsg.x <= (m_oCurrentPoint.X + localWidth)) &&
								(screenPosMsg.y >= m_oCurrentPoint.Y) && (screenPosMsg.y <= (m_oCurrentPoint.Y + localHeight)))
							{
								eatMessage = true;

								OnWM_MOUSEMOVE(screenPosMsg.x, screenPosMsg.y);

								if (m_oHighlightedGroup != null)
									User32.SetCursor(User32.LoadCursor(IntPtr.Zero, (uint)Cursors.IDC_HAND));
								else
									User32.SetCursor(User32.LoadCursor(IntPtr.Zero, (uint)Cursors.IDC_ARROW));								
							}
							else
							{
								if (m_bDrag == true)
								{
									OnWM_MOUSEMOVE(screenPosMsg.x, screenPosMsg.y);
								}
								else
								{
									// clear selection and redraw the window
									if (m_oSelectedItem != null)
									{
										m_oSelectedItem.Selected = false;
										m_oSelectedItem = null;

										RecalcLayout();
										Invalidate();				
									}

									if (m_oHighlightedGroup != null)
									{
										m_oHighlightedGroup = null;

										RecalcLayout();
										Invalidate();
									}		
	
									if (m_bExpandCollapseStrafeSelect == true)
									{
										m_bExpandCollapseStrafeSelect = false;

										RecalcLayout();
										Invalidate();
									}

									if (User32.GetMessage(ref msg, 0, 0, 0))
									{
										User32.TranslateMessage(ref msg);
										User32.DispatchMessage(ref msg);
									}
								}
							}
						}
						#endregion

						#region left button up
						if (msg.message == (int)Msgs.WM_LBUTTONUP)
						{
							POINT screenPosMsg = MousePositionToScreen(msg);
							m_bDrag = false;
							
							// Is the POINT inside the Popup window rectangle
							if ((screenPosMsg.x >= m_oCurrentPoint.X) && (screenPosMsg.x <= (m_oCurrentPoint.X + localWidth)) &&
								(screenPosMsg.y >= m_oCurrentPoint.Y) && (screenPosMsg.y <= (m_oCurrentPoint.Y + localHeight)))
							{
								eatMessage = true;

								POINT localPoint = MousePositionToClient(screenPosMsg); 

								if (OnWM_LBUTTONUP(localPoint.x, localPoint.y) == true)
								{
									Hide();

									return;
								}								
							}
							else
							{
								Hide();

								_exitLoop = true;

								if (User32.GetMessage(ref msg, 0, 0, 0))
								{
									User32.TranslateMessage(ref msg);
									User32.DispatchMessage(ref msg);
								}
							}
						}						
						#endregion						

						#region mouse click events
						if ((msg.message == (int)Msgs.WM_MBUTTONDOWN) ||
							(msg.message == (int)Msgs.WM_RBUTTONDOWN) ||
							(msg.message == (int)Msgs.WM_XBUTTONDOWN) ||
							(msg.message == (int)Msgs.WM_NCLBUTTONDOWN) ||
							(msg.message == (int)Msgs.WM_NCMBUTTONDOWN) ||
							(msg.message == (int)Msgs.WM_NCRBUTTONDOWN) ||
							(msg.message == (int)Msgs.WM_NCXBUTTONDOWN))
						{
							POINT screenPosMsg = MousePositionToScreen(msg);

							// Is the POINT inside the Popup window rectangle
							if ((screenPosMsg.x >= m_oCurrentPoint.X) && (screenPosMsg.x <= (m_oCurrentPoint.X + localWidth)) &&
								(screenPosMsg.y >= m_oCurrentPoint.Y) && (screenPosMsg.y <= (m_oCurrentPoint.Y + localHeight)))
							{
								eatMessage = true;

								// if it is the left mouse then check the drag
								if (msg.message != (int)Msgs.WM_RBUTTONDOWN && msg.message != (int)Msgs.WM_MBUTTONDOWN)
								{								
									// check if it is in the header, if yes, start the dragging mode
									if ((screenPosMsg.x >= m_oCurrentPoint.X) && (screenPosMsg.x <= (m_oCurrentPoint.X + localWidth)) &&
										(screenPosMsg.y >= m_oCurrentPoint.Y) && (screenPosMsg.y <= (m_oCurrentPoint.Y + 10)))
									{
										m_bDrag = true;
									}
									else
										m_bDrag = false;
								}		
							}
							else
							{
								m_bDrag = false;
								Hide();

								_exitLoop = true;

								if (User32.GetMessage(ref msg, 0, 0, 0))
								{
									User32.TranslateMessage(ref msg);
									User32.DispatchMessage(ref msg);
								}
							}
						}
						#endregion

						#region key press
						if (msg.message == (int)Msgs.WM_KEYDOWN)
						{
							switch((int)msg.wParam)
							{
								case (int)VirtualKeys.VK_ESCAPE:
									Hide();
									return;									
							}
						}
						#endregion

						if (eatMessage == true)
						{
							MSG eat = new MSG();
							User32.GetMessage(ref eat, 0, 0, 0);

							eatMessage = false;
						}
						else						
						{
							if (User32.GetMessage(ref msg, 0, 0, 0))
							{
								User32.TranslateMessage(ref msg);
								User32.DispatchMessage(ref msg);
							}
						}
					}
				}
			}
		}
		public ActionMenuItem AddMenuItem(ActionMenuGroup oGroup, string sItem)
		{
			ActionMenuItem oItem = new ActionMenuItem();

			oItem.Text = sItem;
			oItem.MenuGroup = oGroup;
			oGroup.Items.Add(oItem);

			return oItem;
		}
		protected void OnWM_MOUSEMOVE(int xPos, int yPos)
		{
			// Convert from screen to client coordinates
			xPos -= m_oCurrentPoint.X;
			yPos -= m_oCurrentPoint.Y;		
	
			Point pos = new Point(xPos, yPos);

			// Yes, we know the mouse is over window
			m_bMouseOver = true;

			if (m_bDrag == true)
			{
				m_oCurrentPoint = new Point(m_oCurrentPoint.X - (m_oLastMousePos.X - xPos), m_oCurrentPoint.Y - (m_oLastMousePos.Y - yPos));

				// get the max screen size. if the nX + Width or nY + Height is bigger than the area, 
				// them move it elsewhere and recalculate the position
				Screen oScreen = Screen.FromHandle(this.Handle);

				if (m_oCurrentPoint.X + m_oCurrentSize.Width > oScreen.Bounds.Width)
					m_oCurrentPoint.X = oScreen.Bounds.Width - m_oCurrentSize.Width;

				if (m_oCurrentPoint.Y + m_oCurrentSize.Height > oScreen.Bounds.Height)
					m_oCurrentPoint.Y = oScreen.Bounds.Height - m_oCurrentSize.Height;

				RecalcLayout();
				Invalidate();

				return;
			}			
			
			int localWidth = m_oCurrentSize.Width - m_aPosition[0, (int)PaintItem.SW];			

			// Has mouse position really changed since last time?
			if (m_oLastMousePos != pos)
			{
				foreach (Rectangle oRect in m_mapRect2GroupBox.Keys)
				{
					if (oRect.Contains(pos) == true)
					{										
						ActionMenuGroup oGroup = m_mapRect2GroupBox[oRect] as ActionMenuGroup;

						if (m_oHighlightedGroup != oGroup)
						{
							m_oHighlightedGroup = oGroup;

							RecalcLayout();
							Invalidate();

							if (Cursor.Current != System.Windows.Forms.Cursors.Hand)
								Cursor.Current = System.Windows.Forms.Cursors.Hand;
						}

						return;
					}
				}

				foreach (Rectangle oRect in m_mapRect2Item.Keys)
				{
					if (oRect.Contains(pos) == true)
					{
						ActionMenuItem oItem = m_mapRect2Item[oRect] as ActionMenuItem;

						if (oItem.Selected == true)
							return;
					
						if (m_oSelectedItem != null)
							m_oSelectedItem.Selected = false;

						oItem.Selected = true;
						m_oSelectedItem = oItem;
						m_oHighlightedGroup = null;

						RecalcLayout();
						Invalidate();

						return;
					}
				}

				Rectangle oCloseRect = new Rectangle(localWidth - 15, 3, 11, 10);
				
				if (oCloseRect.Contains(pos) == true)
				{
					Cursor.Current = System.Windows.Forms.Cursors.Hand;

					return;
				}

				if (m_oSelectedItem != null)
				{
					m_oSelectedItem.Selected = false;
					m_oSelectedItem = null;

					RecalcLayout();
					Invalidate();				
				}

				if (m_oHighlightedGroup != null)
				{
					m_oHighlightedGroup = null;

					RecalcLayout();
					Invalidate();
				}		
	
				if (m_bExpandCollapseStrafeSelect == true)
				{
					m_bExpandCollapseStrafeSelect = false;

					RecalcLayout();
					Invalidate();
				}						
			}

			// Remember for next time around
			m_oLastMousePos = pos;
		}
		protected bool OnWM_LBUTTONUP()
		{
			try
			{				
				int localWidth = m_oCurrentSize.Width - m_aPosition[0, (int)PaintItem.SW];										

				Rectangle oCloseRect = new Rectangle(localWidth - 15, 3, 11, 10);
			
				if (oCloseRect.Contains(m_oLastMouseDown) == true)
				{
					Cursor.Current = System.Windows.Forms.Cursors.Arrow;

					Hide();

					return true;
				}

				foreach (Rectangle oRect in m_mapRect2GroupBox.Keys)
				{
					if (oRect.Contains(m_oLastMouseDown) == true)
					{
						ActionMenuGroup oGroup = m_mapRect2GroupBox[oRect] as ActionMenuGroup;
						oGroup.Expanded = !oGroup.Expanded;
											
						if (m_oSelectedItem != null)
						{
							m_oSelectedItem.Selected = false;
							m_oSelectedItem = null;
						}

						RecalcLayout();

						// get the max screen size. if the nX + Width or nY + Height is bigger than the area, 
						// them move it elsewhere and recalculate the position
						Screen oScreen = Screen.FromHandle(this.Handle);

						if (m_oCurrentPoint.X + m_oCurrentSize.Width > oScreen.Bounds.Width)
							m_oCurrentPoint.X = oScreen.Bounds.Width - m_oCurrentSize.Width;

						if (m_oCurrentPoint.Y + m_oCurrentSize.Height > oScreen.Bounds.Height)
							m_oCurrentPoint.Y = oScreen.Bounds.Height - m_oCurrentSize.Height;

						Invalidate();

						Cursor.Current = System.Windows.Forms.Cursors.Hand;

						return false;
					}
				}

				if (m_oSelectedItem != null)
				{
					Rectangle oRect = (Rectangle)m_mapItem2Rect[m_oSelectedItem];

					if (oRect.Contains(m_oLastMouseDown) == true)
					{
						this.OnItemClick(m_oSelectedItem);			

						Hide();

						return true;
					}
				}					
			}
			catch (Exception exp)
			{
                exp.ToString();
			}

			return false;
		}
		/// <summary>
		/// Called by the framework when the apply color scheme object is being choosen
		/// </summary>
		/// <param name="oItem">Item clicked</param>
		protected void OnActionMenuTreeViewItemClicked(ActionMenuItem oItem)
		{
			#region menu group section editing

			if (oItem.MenuGroup.Title == "Editing")
			{
				switch (oItem.Text)
				{
					case "Add Node":
						OnAddNode(null, EventArgs.Empty);

						break;
					case "Color Scheme Picker...":
						m_oActionMenuTreeView.Hide();
						OnColorScheme(null, EventArgs.Empty);
						break;
					case "Properties":
						m_oActionMenuTreeView.Hide();
						m_oUIService.ShowToolWindow(System.ComponentModel.Design.StandardToolWindows.PropertyBrowser);
						break;
					case "Copy":
						m_oActionMenuTreeView.Hide();
						OnMenuCopy(this, EventArgs.Empty);
						break;
					case "Paste":
						m_oActionMenuTreeView.Hide();
						OnMenuPaste(this, EventArgs.Empty);
						break;
					case "Delete TreeView":
						m_oActionMenuTreeView.Hide();
						m_oOldDelete.Invoke();
						break;
					case "Clear Content":
						m_oActionMenuTreeView.Hide();

						if (MessageBox.Show(null, "Are you sure you want to delete all nodes?", "TreeView Designer",
						                    MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
							break;

						OnDeleteNodes(this, EventArgs.Empty);

						break;
				}
			}

			#endregion

			#region menu group section layout

			if (oItem.MenuGroup.Title == "Layout")
			{
				switch (oItem.Text)
				{
					case "Bring to Front":
						m_oActionMenuTreeView.Hide();
						m_oOldBringFront.Invoke();
						break;
					case "Send to Back":
						m_oActionMenuTreeView.Hide();
						m_oOldSendBack.Invoke();
						break;
					case "Align to Grid":
						m_oActionMenuTreeView.Hide();
						m_oOldAlignGrid.Invoke();
						break;
					case "Lock Controls":
						m_oActionMenuTreeView.Hide();
						m_oOldLockControls.Invoke();
						break;
				}
			}

			#endregion

			#region menu group section arranging

			if (oItem.MenuGroup.Title == "Arranging")
			{
				switch (oItem.Text)
				{
					case "Expand All":
						m_oTreeView.ExpandAll();
						break;

					case "Collapse All":
						m_oTreeView.CollapseAll();
						break;
				}
			}

			#endregion

			m_oActionMenuTreeView.Hide();
		}
		/// <summary>
		/// Called by the framework when the apply color scheme object is being choosen
		/// </summary>
		/// <param name="sItem">Item clicked</param>
		protected void OnActionMenuNodeItemClicked(ActionMenuItem oItem)
		{
			TreeViewStyleFactory oFactory = TreeViewStyleFactory.GetInstance();
			TreeViewStyle oStyle = null;

			#region menu group section color scheme

			if (oItem.MenuGroup.Title == "Color Schemes")
			{
				m_oActionMenuNode.Hide();

				switch (oItem.Text)
				{
					case "Default":
						oStyle = oFactory.GetDefaultTreeStyle();
						break;
					case "Forest":
						oStyle = oFactory.GetForestTreeStyle();
						break;
					case "Gold":
						oStyle = oFactory.GetGoldTreeStyle();
						break;
					case "Ocean":
						oStyle = oFactory.GetOceanTreeStyle();
						break;
					case "Rose":
						oStyle = oFactory.GetRoseTreeStyle();
						break;
					case "Silver":
						oStyle = oFactory.GetSilverTreeStyle();
						break;
					case "Sky":
						oStyle = oFactory.GetSkyTreeStyle();
						break;
					case "Sunset":
						oStyle = oFactory.GetSunsetTreeStyle();
						break;
					case "Wood":
						oStyle = oFactory.GetWoodTreeStyle();
						break;
					default:
						oStyle = oFactory.GetDefaultTreeStyle();
						break;
				}

				string sTransaction = "Applying style";

				if (m_oSelectedNode != null)
					sTransaction = "Applying style to Node [" + m_oSelectedNode.GetText() + "]";

				using (DesignerTransaction oTransaction = m_oDesignerHost.CreateTransaction(sTransaction))
				{
					// check the selected component and apply the style
					if (m_oSelectedNode != null)
					{
						NodeStyle oOldStyle = m_oSelectedNode.GetNodeStyle();
						NodeStyleSource eOldStyleSource = m_oSelectedNode.NodeStyleSource;

						PropertyDescriptorCollection aProperties = TypeDescriptor.GetProperties(m_oSelectedNode);
						PropertyDescriptor oNodeStyleProperty = aProperties.Find("NodeStyle", false);
						PropertyDescriptor oNodeStyleSourceProperty = aProperties.Find("NodeStyleSource", false);

						try
						{
							RaiseComponentChanging(oNodeStyleProperty);
						}
						catch
						{
						}
						try
						{
							RaiseComponentChanging(oNodeStyleSourceProperty);
						}
						catch
						{
						}

						if (m_oSelectedNode.NodeStyle != null)
							oStyle.NodeStyle.SelectedFillStyle = m_oSelectedNode.NodeStyle.SelectedFillStyle;
						else
							oStyle.NodeStyle.SelectedFillStyle = m_oTreeView.Style.NodeStyle.SelectedFillStyle;

						oNodeStyleSourceProperty.SetValue(m_oSelectedNode, NodeStyleSource.Local);
						oNodeStyleProperty.SetValue(m_oSelectedNode, oStyle.NodeStyle);

						try
						{
							RaiseComponentChanged(oNodeStyleProperty, oOldStyle, m_oSelectedNode.NodeStyle);
						}
						catch
						{
						}
						try
						{
							RaiseComponentChanged(oNodeStyleSourceProperty, eOldStyleSource, m_oSelectedNode.NodeStyleSource);
						}
						catch
						{
						}
					}

					oTransaction.Commit();
				}
			}

			#endregion

			#region menu group section arranging

			if (oItem.MenuGroup.Title == "Arranging")
			{
				PropertyDescriptorCollection aProperties = TypeDescriptor.GetProperties(m_oSelectedNode);
				PropertyDescriptor oParentProperty = aProperties.Find("Parent", false);

				try
				{
					RaiseComponentChanging(oParentProperty);
				}
				catch
				{
				}

				switch (oItem.Text)
				{
					case "Move Top":
						m_oActionMenuNode.Hide();
						m_oSelectedNode.MoveTop();
						break;
					case "Move Bottom":
						m_oActionMenuNode.Hide();
						m_oSelectedNode.MoveBottom();
						break;
					case "Move Down":
						m_oActionMenuNode.Hide();
						m_oSelectedNode.MoveDown();
						break;
					case "Move Up":
						m_oActionMenuNode.Hide();
						m_oSelectedNode.MoveUp();
						break;
					case "Move Left":
						m_oActionMenuNode.Hide();
						m_oSelectedNode.MoveLeft();
						break;
					case "Move Right":
						m_oActionMenuNode.Hide();
						m_oSelectedNode.MoveRight();
						break;
					case "Expand":
						m_oActionMenuNode.Hide();
						m_oSelectedNode.ExpandAll();
						break;
					case "Collapse":
						m_oActionMenuNode.Hide();
						m_oSelectedNode.CollapseAll();
						break;
				}

				try
				{
					RaiseComponentChanged(oParentProperty, null, m_oTreeView.Nodes);
				}
				catch
				{
				}
			}

			#endregion

			#region menu group section editing

			if (oItem.MenuGroup.Title == "Editing")
			{
				switch (oItem.Text)
				{
					case "Add Node":
						m_oActionMenuNode.Hide();
						OnAddNode(null, EventArgs.Empty);
						break;
					case "Add Panel":
						m_oActionMenuNode.Hide();
						OnAddPanel(null, EventArgs.Empty);
						break;
					case "Delete Node":
						m_oActionMenuNode.Hide();
						OnDeleteNode(null, EventArgs.Empty);
						break;
					case "Delete TreeView":
						m_oActionMenuNode.Hide();
						// select tree view
						m_oSelectionService.SetSelectedComponents(new Component[] {m_oTreeView});
						m_oOldDelete.Invoke();
						break;
					case "Clear Content":
						m_oActionMenuNode.Hide();

						if (MessageBox.Show(null, "Are you sure you want to delete all nodes?", "TreeView Designer",
						                    MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
							break;

						OnDeleteNodes(this, EventArgs.Empty);

						break;
					case "Properties":
						m_oActionMenuNode.Hide();
						m_oUIService.ShowToolWindow(System.ComponentModel.Design.StandardToolWindows.PropertyBrowser);
						break;
					case "Copy":
						m_oActionMenuNode.Hide();
						OnMenuCopy(this, EventArgs.Empty);
						break;
					case "Paste":
						m_oActionMenuNode.Hide();
						OnMenuPaste(this, EventArgs.Empty);
						break;
				}
			}

			#endregion			

			m_oActionMenuNode.Hide();
		}