DesignerHelpers.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Common / AuthoringOM / Design / DesignerHelpers.cs / 1305376 / DesignerHelpers.cs

                            namespace System.Workflow.ComponentModel.Design 
{
 	using System;
	using System.IO;
	using System.CodeDom; 
    using System.CodeDom.Compiler;
    using System.Drawing; 
	using System.Resources; 
 	using System.Reflection;
	using System.Collections; 
 	using System.Collections.ObjectModel;
 	using System.Diagnostics;
	using System.Globalization;
 	using System.Drawing.Text; 
	using System.Windows.Forms;
    using System.Windows.Forms.Design; 
    using System.ComponentModel; 
    using System.Drawing.Imaging;
    using System.Drawing.Drawing2D; 
	using System.Collections.Generic;
	using System.ComponentModel.Design;
 	using System.Runtime.InteropServices;
	using System.Workflow.Interop; 
 	using System.Workflow.ComponentModel.Compiler;
    using Microsoft.Win32; 
 	using System.Runtime.CompilerServices; 

    #region Enum LightSourcePosition 
    [Flags]
    internal enum LightSourcePosition
    {
        Left = 1, 
        Right = 2,
        Top = 4, 
        Bottom = 8, 
        Center = 16
    } 
    #endregion

	#region Class ActivityDesignerPaint
    ///  
    /// Provides useful methods used to paint user interface elements on activity designers.
    ///  
 	public static class ActivityDesignerPaint 
    {
		#region Members and Enumerations 

        internal enum XpThemeColorStyles { Blue = 0, Silver = 1, Green = 2 }
		private enum XpSchemeColorIndex { FgGnd = 0, BkGnd = 1, Border = 2, Highlight = 3, Shadow = 4 };
		private static Color[,] XPColorSchemes = new Color[,] 
 			{
				{ Color.FromArgb(0,60,165), Color.FromArgb(255,255,255), Color.FromArgb(181,186,214), Color.FromArgb(66,142,255), Color.FromArgb(181,195,231) }, 
 				{ Color.FromArgb(49,68,115), Color.FromArgb(255,255,255), Color.FromArgb(186,187,201), Color.FromArgb(126,124,124), Color.FromArgb(206,207,216) }, 
 				{ Color.FromArgb(86,102,45), Color.FromArgb(255,255,255), Color.FromArgb(210,219,197), Color.FromArgb(114,146,29), Color.FromArgb(212,220,190) }
			}; 
 		#endregion

		#region Drawing Functions
		#region Text Rendering 
		internal static Size MeasureString(Graphics graphics, Font font, string text, StringAlignment alignment, Size maxSize)
 		{ 
			SizeF textSize = SizeF.Empty; 
 			if (maxSize.IsEmpty)
 			{ 
				textSize = graphics.MeasureString(text, font);
 			}
			else
			{ 
				StringFormat format = new StringFormat();
 				format.Alignment = alignment; 
				format.LineAlignment = StringAlignment.Center; 
 				format.Trimming = StringTrimming.EllipsisCharacter;
 				format.FormatFlags = StringFormatFlags.NoClip; 
				textSize = graphics.MeasureString(text, font, new SizeF(maxSize.Width, maxSize.Height), format);
 			}

			return new Size(Convert.ToInt32(Math.Ceiling(textSize.Width)), Convert.ToInt32(Math.Ceiling(textSize.Height))); 
		}
 
        ///  
        /// Draws the text as per the parameters specified on given graphics object
        ///  
        /// Graphics on which to draw the text
        /// Font used in drawing
        /// Text to draw on the graphics
        /// Bounding rectangle in which text must be drawn 
        /// Alignment for the text
        /// Text quality to be used in drawing 
        /// Brush using which to draw the text 
        public static void DrawText(Graphics graphics, Font font, string text, Rectangle boundingRect, StringAlignment alignment, TextQuality textQuality, Brush textBrush)
        { 
			if (graphics == null)
 				throw new ArgumentNullException("graphics");

			if (font == null) 
 				throw new ArgumentNullException("font");
 
 			if (text == null) 
				throw new ArgumentNullException("text");
 
 			if (textBrush == null)
				throw new ArgumentNullException("textBrush");

			if (boundingRect.IsEmpty) 
				return;
 
            StringFormat format = new StringFormat(); 
            format.Alignment = alignment;
            format.LineAlignment = StringAlignment.Center; 
            format.Trimming = StringTrimming.EllipsisCharacter;
            format.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.FitBlackBox;

            TextRenderingHint oldTextHint = graphics.TextRenderingHint; 
 			graphics.TextRenderingHint = (textQuality == TextQuality.AntiAliased) ? TextRenderingHint.AntiAlias :  TextRenderingHint.SystemDefault;
			graphics.DrawString(text, font, textBrush, boundingRect, format); 
 			graphics.TextRenderingHint = oldTextHint; 
 		}
		#endregion 

 		#region Image Rendering
        /// 
        /// Draws image with specified paramters. 
        /// 
        /// Graphics on which to draw the image 
        /// Image to be drawn 
        /// Bounding rectangle for the image
        /// Alignment specifying how the image will be aligned against bounding rectangle 
		public static void DrawImage(Graphics graphics, Image image, Rectangle destination, DesignerContentAlignment alignment)
		{
			if (image == null)
 				throw new ArgumentNullException("image");//we are accessing .Size property on the "image" argument 

			DrawImage(graphics, image, destination, new Rectangle(Point.Empty, image.Size), alignment, 1.0f, false); 
 		} 

 		internal static void DrawImage(Graphics graphics, Image image, Rectangle destination, float transparency) 
		{
 			if (image == null)
				throw new ArgumentNullException("image");//we are accessing .Size property on the "image" argument
 
			DrawImage(graphics, image, destination, new Rectangle(Point.Empty, image.Size), DesignerContentAlignment.Center, transparency, false);
		} 
 
        /// 
        /// Draws image with specified paramters. 
        /// 
        /// Graphics on which to draw image
        /// Image to be drawn
 		/// Bounding rectangle for the image 
		/// Source rectangle of the image
        /// Alignment specifying how image will be aligned against the bounding rectangle 
        /// Transparency for the image 
        /// Value indicating if the image should be gray scaled
 		public static void DrawImage(Graphics graphics, Image image, Rectangle destination, Rectangle source, DesignerContentAlignment alignment, float transparency, bool grayscale) 
 		{
			if (graphics == null)
 				throw new ArgumentNullException("graphics");
 
			if (image == null)
				throw new ArgumentNullException("image"); 
 
			if (destination.IsEmpty)
 				throw new ArgumentNullException("destination"); 

			if (source.IsEmpty)
 				throw new ArgumentNullException("source");
 
 			if (transparency < 0 || transparency > 1.0f)
				throw new ArgumentNullException("transparency"); 
 
 			Rectangle imageRectangle = GetRectangleFromAlignment(alignment, destination, source.Size);
			if (image != null && !imageRectangle.IsEmpty) 
			{
				ColorMatrix colorMatrix = new ColorMatrix();
 				if (grayscale)
				{ 
 					colorMatrix.Matrix00 = 1 / 3f;
 					colorMatrix.Matrix01 = 1 / 3f; 
					colorMatrix.Matrix02 = 1 / 3f; 
 					colorMatrix.Matrix10 = 1 / 3f;
					colorMatrix.Matrix11 = 1 / 3f; 
					colorMatrix.Matrix12 = 1 / 3f;
					colorMatrix.Matrix20 = 1 / 3f;
 					colorMatrix.Matrix21 = 1 / 3f;
					colorMatrix.Matrix22 = 1 / 3f; 
 				}
 				colorMatrix.Matrix33 = transparency; //Alpha factor 
 
				ImageAttributes imageAttributes = new ImageAttributes();
 				imageAttributes.SetColorMatrix(colorMatrix); 
				graphics.DrawImage(image, imageRectangle, source.X, source.Y, source.Width, source.Height, GraphicsUnit.Pixel, imageAttributes);
			}
		}
 
 		internal static Rectangle GetRectangleFromAlignment(DesignerContentAlignment alignment, Rectangle destination, Size size)
		{ 
 			if (size.IsEmpty || destination.IsEmpty) 
 				return Rectangle.Empty;
 
			Rectangle rectangle = Rectangle.Empty;
 			rectangle.Width = Math.Min(size.Width, destination.Width);
			rectangle.Height = Math.Min(size.Height, destination.Height);
 
			if ((alignment & DesignerContentAlignment.Fill) > 0)
			{ 
 				rectangle = destination; 
			}
 			else 
 			{
				if ((alignment & DesignerContentAlignment.Left) > 0)
 					rectangle.X = destination.Left;
				else if ((alignment & DesignerContentAlignment.Right) > 0) 
					rectangle.X = destination.Right - rectangle.Width;
				else 
 					rectangle.X = destination.Left + destination.Width / 2 - rectangle.Width / 2; 

				if ((alignment & DesignerContentAlignment.Top) > 0) 
 					rectangle.Y = destination.Top;
 				else if ((alignment & DesignerContentAlignment.Bottom) > 0)
					rectangle.Y = destination.Bottom - rectangle.Height;
 				else 
					rectangle.Y = destination.Top + destination.Height / 2 - rectangle.Height / 2;
			} 
 
			return rectangle;
 		} 
		#endregion

 		#region Selection Rendering
        internal static void DrawSelection(Graphics graphics, Rectangle boundingRect, bool isPrimary, Size selectionSize, Rectangle[] grabHandles) 
        {
            InterpolationMode oldInterpolationMode = graphics.InterpolationMode; 
            SmoothingMode oldSmoothingMode = graphics.SmoothingMode; 

            //dashes dont show up when smoothing is set 
            graphics.InterpolationMode = InterpolationMode.High;
            graphics.SmoothingMode = SmoothingMode.None;

            Rectangle selectionRect = boundingRect; 
            selectionRect.Inflate(selectionSize.Width, selectionSize.Height);
 
            selectionRect.Inflate(-selectionSize.Width / 2, -selectionSize.Height / 2); 
            graphics.DrawRectangle(WorkflowTheme.CurrentTheme.AmbientTheme.SelectionPatternPen, selectionRect);
 
            selectionRect.Inflate(selectionSize.Width / 2, selectionSize.Height / 2);

            DrawGrabHandles(graphics, grabHandles, isPrimary);
 
            graphics.InterpolationMode = oldInterpolationMode;
            graphics.SmoothingMode = oldSmoothingMode; 
        } 

        internal static void DrawGrabHandles(Graphics graphics, Rectangle[] grabHandles, bool isPrimary) 
        {
            foreach (Rectangle grabHandle in grabHandles)
            {
                if (isPrimary) 
 				{
                    //primary 
                    graphics.FillRectangle(Brushes.White, grabHandle); 
                    graphics.DrawRectangle(WorkflowTheme.CurrentTheme.AmbientTheme.SelectionForegroundPen, grabHandle);
				} 
 				else
				{
                    Pen patternPen = WorkflowTheme.CurrentTheme.AmbientTheme.SelectionPatternPen;
                    DashStyle oldDashStyle = patternPen.DashStyle; 
                    patternPen.DashStyle = DashStyle.Solid;
 
                    //secondary 
					graphics.FillRectangle(Brushes.White, grabHandle);
                    graphics.DrawRectangle(patternPen, grabHandle); 

                    patternPen.DashStyle = oldDashStyle;
				}
            } 
        }
 		#endregion 
 
		#region General Rendering Methods
        ///  
        /// Draws three dimentional button on the designer
        /// 
        /// Graphics on which to draw the button
        /// Image which is to be drawn on the button 
        /// Bounding rectangle for the button
        /// Transparency value for the button 
        /// State in which to draw the button 
 		public static void Draw3DButton(Graphics graphics, Image image, Rectangle bounds, float transparency, ButtonState buttonState)
 		{ 
			if (graphics == null)
 				throw new ArgumentNullException("graphics");

			int alpha = Math.Max(0, Convert.ToInt32(transparency * 255)); 
			using (SolidBrush backgroundBrush = new SolidBrush(Color.FromArgb(alpha, SystemColors.Control)))
			using (Pen lightPen = new Pen(Color.FromArgb(alpha, SystemColors.ControlLightLight))) 
 			using (Pen darkPen = new Pen(Color.FromArgb(alpha, SystemColors.ControlDark))) 
			using (Pen darkdarkPen = new Pen(Color.FromArgb(alpha, SystemColors.ControlDarkDark)))
 			{ 
 				graphics.FillRectangle(backgroundBrush, bounds);

				if (buttonState == ButtonState.Normal || buttonState == ButtonState.Inactive)
 				{ 
					graphics.DrawLine(lightPen, bounds.Left + 1, bounds.Bottom - 1, bounds.Left + 1, bounds.Top + 1);
					graphics.DrawLine(lightPen, bounds.Left + 1, bounds.Top + 1, bounds.Right - 1, bounds.Top + 1); 
					graphics.DrawLine(darkPen, bounds.Left + 1, bounds.Bottom - 1, bounds.Right - 1, bounds.Bottom - 1); 
 					graphics.DrawLine(darkPen, bounds.Right - 1, bounds.Bottom - 1, bounds.Right - 1, bounds.Top + 1);
					graphics.DrawLine(darkdarkPen, bounds.Left, bounds.Bottom, bounds.Right, bounds.Bottom); 
 					graphics.DrawLine(darkdarkPen, bounds.Right, bounds.Bottom, bounds.Right, bounds.Top);
 				}
				else if (buttonState == ButtonState.Pushed)
 				{ 
					graphics.DrawRectangle(darkPen, bounds);
					bounds.Offset(1, 1); 
				} 

 				if (image != null) 
				{
 					bounds.Inflate(-2, -2);
 					DrawImage(graphics, image, bounds, new Rectangle(Point.Empty, image.Size), DesignerContentAlignment.Fill, transparency, (buttonState == ButtonState.Inactive));
				} 
 			}
		} 
 
		internal static void DrawGrid(Graphics graphics, Rectangle viewableRectangle)
		{ 
 			AmbientTheme ambientTheme = WorkflowTheme.CurrentTheme.AmbientTheme;
			if (ambientTheme.GridStyle == DashStyle.Dot)
 			{
 				Point gridStart = Point.Empty; 
				gridStart.X = viewableRectangle.X - (viewableRectangle.X % ambientTheme.GridSize.Width);
 				gridStart.Y = viewableRectangle.Y - (viewableRectangle.Y % ambientTheme.GridSize.Height); 
 
				for (int gridCoOrdX = gridStart.X; gridCoOrdX <= viewableRectangle.Right; gridCoOrdX += Math.Max(ambientTheme.GridSize.Width, 1))
				{ 
					for (int gridCoOrdY = gridStart.Y; gridCoOrdY <= viewableRectangle.Bottom; gridCoOrdY += Math.Max(ambientTheme.GridSize.Height, 1))
 					{
						graphics.FillRectangle(ambientTheme.MajorGridBrush, new Rectangle(new Point(gridCoOrdX, gridCoOrdY), new Size(1, 1)));
 
 						if (((gridCoOrdX + ambientTheme.GridSize.Width / 2) >= viewableRectangle.Left && (gridCoOrdX + ambientTheme.GridSize.Width / 2) <= viewableRectangle.Right) &&
 							((gridCoOrdY + ambientTheme.GridSize.Height / 2) >= viewableRectangle.Top && (gridCoOrdY + ambientTheme.GridSize.Height / 2) <= viewableRectangle.Bottom)) 
							graphics.FillRectangle(ambientTheme.MinorGridBrush, new Rectangle(new Point(gridCoOrdX + ambientTheme.GridSize.Width / 2, gridCoOrdY + ambientTheme.GridSize.Height / 2), new Size(1, 1))); 
 					}
				} 
			}
			else
 			{
				//We use native pens to draw the grid for efficiency reason 
 				using (Hdc hdc = new Hdc(graphics))
 				using (HPen majorGridPen = new HPen(ambientTheme.MajorGridPen)) 
				using (HPen minorGridPen = new HPen(ambientTheme.MinorGridPen)) 
 				{
					hdc.DrawGrid(majorGridPen, minorGridPen, viewableRectangle, ambientTheme.GridSize, true); 
				}
			}
 		}
 
        /// 
        /// Draws expand / collapse button based on the theme passed 
        ///  
        /// Graphics on which to draw the button
        /// Bounding rectangle for the button 
        /// Value indicating if the button should be drawn in expanded state
        /// Theme associated with the designer used in rendering of the button
		public static void DrawExpandButton(Graphics graphics, Rectangle boundingRect, bool drawExpanded, CompositeDesignerTheme compositeDesignerTheme)
 		{ 
 			if (graphics == null)
				throw new ArgumentNullException("graphics"); 
 
 			if (compositeDesignerTheme == null)
				throw new ArgumentNullException("compositeDesignerTheme"); 

			if (boundingRect.IsEmpty)
				return;
 
 			graphics.FillRectangle(compositeDesignerTheme.GetExpandButtonBackgroundBrush(boundingRect), boundingRect);
			graphics.DrawRectangle(CompositeDesignerTheme.ExpandButtonBorderPen, boundingRect); 
 
 			graphics.DrawLine(CompositeDesignerTheme.ExpandButtonForegoundPen, boundingRect.Left + 2, boundingRect.Top + boundingRect.Height / 2, boundingRect.Right - 2, boundingRect.Top + boundingRect.Height / 2);
 			if (drawExpanded) 
				graphics.DrawLine(CompositeDesignerTheme.ExpandButtonForegoundPen, boundingRect.Left + boundingRect.Width / 2, boundingRect.Top + 2, boundingRect.Left + boundingRect.Width / 2, boundingRect.Bottom - 2);
 		}

        ///  
        /// Draws a rounded rectangle with specified parameters
        ///  
        /// Graphics on which to draw the rounded rectangle 
        /// Pen used to render the rectangle
        /// Bounding rectangle 
        /// Radius used for the rounded edges
		public static void DrawRoundedRectangle(Graphics graphics, Pen drawingPen, Rectangle rectangle, int radius)
		{
			if (graphics == null) 
 				throw new ArgumentNullException("graphics");
 
			if (drawingPen == null) 
 				throw new ArgumentNullException("drawingPen");
 
            GraphicsPath roundedRectangle = null;

            checked
            { 
                roundedRectangle = GetRoundedRectanglePath(rectangle, radius * 2);
            } 
            graphics.DrawPath(drawingPen, roundedRectangle); 
 			roundedRectangle.Dispose();
		} 

        /// 
        /// Draws the drop shadow using specified base color
        ///  
        /// Graphics object on which to draw the shadow
        /// Rectangle around which to draw the shadow 
        /// Base color used to draw the shadow 
        /// Depth of the shadow, this has to be between 1 and 12 inclusive
        /// Position of the light source determining the way shadow will be drawn 
        /// Intensity of the light source, this needs to be inbetween 0.01 and 1
        /// Flag indicating whether to round the edges of the shadow
        internal static void DrawDropShadow(Graphics graphics, Rectangle shadowSourceRectangle, Color baseColor, int shadowDepth, LightSourcePosition lightSourcePosition, float lightSourceIntensity, bool roundEdges)
        { 
            if (graphics == null)
                throw new ArgumentNullException("graphics"); 
 
            if (shadowSourceRectangle.IsEmpty || shadowSourceRectangle.Width < 0 || shadowSourceRectangle.Height < 0)
                throw new ArgumentException(SR.GetString(SR.Error_InvalidShadowRectangle), "shadowRectangle"); 

            if (shadowDepth < 1 || shadowDepth > 12)
                throw new ArgumentException(SR.GetString(SR.Error_InvalidShadowDepth), "shadowDepth");
 
            if (lightSourceIntensity <= 0.0f || lightSourceIntensity > 1.0f)
                throw new ArgumentException(SR.GetString(SR.Error_InvalidLightSource), "lightSourceIntensity"); 
 
            const int baseAlphaLevel = 40;
            Rectangle shadowRectangle = shadowSourceRectangle; 

            Size offset = Size.Empty;
            if ((lightSourcePosition & LightSourcePosition.Center) > 0)
                shadowRectangle.Inflate(shadowDepth, shadowDepth); 

            if ((lightSourcePosition & LightSourcePosition.Left) > 0) 
                offset.Width += (shadowDepth + 1); 
            else if ((lightSourcePosition & LightSourcePosition.Right) > 0)
                offset.Width -= (shadowDepth + 1); 
            if ((lightSourcePosition & LightSourcePosition.Top) > 0)
                offset.Height += (shadowDepth + 1);
            else if ((lightSourcePosition & LightSourcePosition.Bottom) > 0)
                offset.Height -= (shadowDepth + 1); 
            shadowRectangle.Offset(offset.Width, offset.Height);
 
            GraphicsContainer graphicsState = graphics.BeginContainer(); 
            GraphicsPath excludePath = new GraphicsPath();
            if (roundEdges) 
                excludePath.AddPath(GetRoundedRectanglePath(shadowSourceRectangle, AmbientTheme.ArcDiameter), true);
            else
                excludePath.AddRectangle(shadowSourceRectangle);
 
            try
            { 
                using (Region clipRegion = new Region(excludePath)) 
                {
                    graphics.SmoothingMode = SmoothingMode.AntiAlias; 
                    graphics.ExcludeClip(clipRegion);
                    Color shadowColor = Color.FromArgb(Convert.ToInt32((baseAlphaLevel * lightSourceIntensity)), baseColor);
                    int alphaIncreament = Math.Max((baseAlphaLevel / shadowDepth), 2);
 
                    for (int i = 0; i < shadowDepth; i++)
                    { 
                        shadowRectangle.Inflate(-1, -1); 

                        using (Brush shadowBrush = new SolidBrush(shadowColor)) 
                        using (GraphicsPath shadowPath = new GraphicsPath())
                        {
                            if (roundEdges)
                                shadowPath.AddPath(GetRoundedRectanglePath(shadowRectangle, AmbientTheme.ArcDiameter), true); 
                            else
                                shadowPath.AddRectangle(shadowRectangle); 
                            graphics.FillPath(shadowBrush, shadowPath); 
                        }
                        shadowColor = Color.FromArgb(shadowColor.A + alphaIncreament, shadowColor.R, shadowColor.G, shadowColor.B); 
                    }
                }
            }
            finally 
            {
                graphics.EndContainer(graphicsState); 
            } 
        }
 
 		internal static void DrawDesignerBackground(Graphics graphics, ActivityDesigner designer)
		{
			ActivityDesignerTheme designerTheme = designer.DesignerTheme;
			CompositeDesignerTheme compositeDesignerTheme = designerTheme as CompositeDesignerTheme; 

            //Draw the designer 
            Rectangle designerBounds = designer.Bounds; 
            Point location = designerBounds.Location;
            designerBounds.Location = Point.Empty; 

            Matrix oldMatrix = graphics.Transform;
            graphics.TranslateTransform(location.X, location.Y);
 
            GraphicsPath designerPath = GetDesignerPath(designer, new Point(-location.X, -location.Y), Size.Empty, DesignerEdges.None);
            RectangleF boundsF = designerPath.GetBounds(); 
            Rectangle bounds = new Rectangle(0, 0, Convert.ToInt32(Math.Ceiling(boundsF.Width)), Convert.ToInt32(Math.Ceiling(boundsF.Height))); 

            //Draw background 
            graphics.FillPath(designerTheme.GetBackgroundBrush(bounds), designerPath);

            //Draw watermark, we draw the watermark only when the designer is not collapsed
 			bool expanded = (designer is CompositeActivityDesigner) ? ((CompositeActivityDesigner)designer).Expanded : false; 
			if (compositeDesignerTheme != null && expanded && compositeDesignerTheme.WatermarkImage != null)
 			{ 
 				Size margin = WorkflowTheme.CurrentTheme.AmbientTheme.Margin; 
				bounds.Inflate(-margin.Width, -margin.Height);
 				DrawImage(graphics, compositeDesignerTheme.WatermarkImage, bounds, new Rectangle(Point.Empty, compositeDesignerTheme.WatermarkImage.Size), compositeDesignerTheme.Watermar----gnment, AmbientTheme.WatermarkTransparency, false); 
			}

			//Draw border
			if (WorkflowTheme.CurrentTheme.AmbientTheme.ShowDesignerBorder) 
 				graphics.DrawPath(designerTheme.BorderPen, designerPath);
 
			designerPath.Dispose(); 
 			graphics.Transform = oldMatrix;
 		} 

		internal static GraphicsPath GetDesignerPath(ActivityDesigner designer, bool enableRoundedCorners)
 		{
			return GetDesignerPath(designer, Point.Empty, Size.Empty, DesignerEdges.None, enableRoundedCorners); 
		}
 
		internal static GraphicsPath GetDesignerPath(ActivityDesigner designer, Point offset, Size inflate, DesignerEdges edgeToInflate) 
 		{
			return GetDesignerPath(designer, offset, inflate, edgeToInflate, true); 
 		}

        internal static GraphicsPath GetDesignerPath(ActivityDesigner designer, Point offset, Size inflate, DesignerEdges edgeToInflate, bool enableRoundedCorners)
 		{ 
			GraphicsPath designerPath = new GraphicsPath();
 
            Rectangle bounds = designer.Bounds; 
            bounds.Offset(offset);
 
            if ((edgeToInflate & DesignerEdges.Left) > 0)
            {
                bounds.X -= inflate.Width;
                bounds.Width += inflate.Width; 
            }
 
            if ((edgeToInflate & DesignerEdges.Right) > 0) 
                bounds.Width += inflate.Width;
 
            if ((edgeToInflate & DesignerEdges.Top) > 0)
            {
                bounds.Y -= inflate.Height;
                bounds.Height += inflate.Height; 
            }
 
            if ((edgeToInflate & DesignerEdges.Bottom) > 0) 
                bounds.Height += inflate.Height;
 
            //
            if (designer == ActivityDesigner.GetSafeRootDesigner(designer.Activity.Site) && ((IWorkflowRootDesigner)designer).InvokingDesigner == null)
            {
                designerPath.AddRectangle(bounds); 
            }
            else 
            { 
 				ActivityDesignerTheme designerTheme = designer.DesignerTheme;
				if (enableRoundedCorners && designerTheme != null && designerTheme.DesignerGeometry == DesignerGeometry.RoundedRectangle) 
                    designerPath.AddPath(GetRoundedRectanglePath(bounds, AmbientTheme.ArcDiameter), true);
                else
					designerPath.AddRectangle(bounds);
			} 

 			return designerPath; 
		} 

 		internal static void DrawInvalidDesignerIndicator(Graphics graphics, ActivityDesigner activityDesigner) 
 		{
			Rectangle bounds = activityDesigner.Bounds;
 			graphics.DrawRectangle(Pens.Red, bounds);
			graphics.DrawLine(Pens.Red, bounds.Left, bounds.Top, bounds.Right, bounds.Bottom); 
			graphics.DrawLine(Pens.Red, bounds.Right, bounds.Top, bounds.Left, bounds.Bottom);
		} 
 		#endregion 

		#region Connector Drawing 
        internal static void DrawConnectors(Graphics graphics, Pen pen, Point[] points, Size connectorCapSize, Size maxCapSize, LineAnchor startConnectorCap, LineAnchor endConnectorCap)
        {
 			if (points.GetLength(0) < 2)
 				return; 

			//First we start with drawing start cap 
 			GraphicsPath startCap = null; 
			float startCapInset = 0.0f;
			if (startConnectorCap != LineAnchor.None) 
			{
 				Point[] startSegment = new Point[] { points[0], points[1] };
                int capSize = (startSegment[0].Y == startSegment[1].Y) ? connectorCapSize.Width : connectorCapSize.Height;
                capSize += (capSize % 2); 
                capSize = Math.Min(Math.Min(capSize, maxCapSize.Width), maxCapSize.Height);
                startCap = GetLineCap(startConnectorCap, capSize, out startCapInset); 
 
				//Now if user has requested us to fill the line cap then we do so
 				//THIS IS A WORKAROUND IN FILLING THE CUSTOM CAPS AS GDI+ HAS A 
 				bool fill = (startCap != null && (((int) startConnectorCap % 2) == 0) && (startSegment[0].X == startSegment[1].X || startSegment[0].Y == startSegment[1].Y));
				if (fill)
 				{
					Matrix oldTransform = graphics.Transform; 
					graphics.TranslateTransform(startSegment[0].X, startSegment[0].Y);
					if (startSegment[0].Y == startSegment[1].Y) 
 						graphics.RotateTransform((startSegment[0].X < startSegment[1].X) ? 90.0f : 270.0f); 
					else
                        graphics.RotateTransform((startSegment[0].Y < startSegment[1].Y) ? 180.0f : 0.0f); 
                    using (Brush penBrush = new SolidBrush(pen.Color))
                    {
                        graphics.FillPath(penBrush, startCap);
                        graphics.DrawPath(pen, startCap); 
                    }
 					graphics.Transform = (oldTransform != null) ? oldTransform : new Matrix(); 
 				} 
			}
 
 			GraphicsPath endCap = null;
			float endCapInset = 0.0f;
			if (endConnectorCap != LineAnchor.None)
			{ 
 				Point[] endSegment = new Point[] { points[points.GetLength(0) - 2], points[points.GetLength(0) - 1] };
                int capSize = (endSegment[0].Y == endSegment[1].Y) ? connectorCapSize.Width : connectorCapSize.Height; 
                capSize += (capSize % 2); 
                capSize = Math.Min(Math.Min(capSize, maxCapSize.Width), maxCapSize.Height);
                endCap = GetLineCap(endConnectorCap, capSize, out endCapInset); 

				//Now if user has requested us to fill the line cap then we do so,
 				//THIS IS A WORKAROUND IN FILLING THE CUSTOM CAPS AS GDI+ HAS A
 				bool fill = (endCap != null && (((int) endConnectorCap % 2) == 0) && (endSegment[0].X == endSegment[1].X || endSegment[0].Y == endSegment[1].Y)); 
				if (fill)
 				{ 
					Matrix oldTransform = graphics.Transform; 
					graphics.TranslateTransform(endSegment[1].X, endSegment[1].Y);
					if (endSegment[0].Y == endSegment[1].Y) 
 						graphics.RotateTransform((endSegment[0].X < endSegment[1].X) ? 270.0f : 90.0f);
                    else
                        graphics.RotateTransform((endSegment[0].Y < endSegment[1].Y) ? 0.0f : 180.0f);
                    using (Brush penBrush = new SolidBrush(pen.Color)) 
                    {
                        graphics.FillPath(penBrush, endCap); 
                        graphics.DrawPath(pen, endCap); 
                    }
					graphics.Transform = (oldTransform != null) ? oldTransform : new Matrix(); 
 				}
 			}

			if (startCap != null) 
 			{
				CustomLineCap customStartCap = new CustomLineCap(null, startCap); 
				customStartCap.WidthScale = 1.0f / pen.Width; 
				customStartCap.BaseInset = startCapInset;
 				pen.CustomStartCap = customStartCap; 
			}

 			if (endCap != null)
 			{ 
				CustomLineCap customEndCap = new CustomLineCap(null, endCap);
 				customEndCap.WidthScale = 1.0f / pen.Width; 
				customEndCap.BaseInset = endCapInset; 
				pen.CustomEndCap = customEndCap;
			} 

 			graphics.DrawLines(pen, points);

			if (startCap != null) 
 			{
 				CustomLineCap disposableLineCap = pen.CustomStartCap; 
				pen.StartCap = LineCap.Flat; 
 				disposableLineCap.Dispose();
			} 

			if (endCap != null)
			{
 				CustomLineCap disposableLineCap = pen.CustomEndCap; 
				pen.EndCap = LineCap.Flat;
 				disposableLineCap.Dispose(); 
 			} 
		}
 		#endregion 

		#region General purpose functions
		//
 
 		internal static GraphicsPath GetLineCap(LineAnchor lineCap, int capsize, out float capinset)
		{ 
 			//WE DO NOT SUPPORT ARROWCAPS FOR ANGULAR CONNECTORS FOR NOW 
 			capinset = 0.0f;
			capinset = (float)capsize; 
 			Size capSize = new Size(capsize, capsize);

			GraphicsPath lineCapPath = new GraphicsPath();
			switch (lineCap) 
			{
 				case LineAnchor.Arrow: 
				case LineAnchor.ArrowAnchor: 
 					int arcRadius = capSize.Height / 3;
 					lineCapPath.AddLine(capSize.Width / 2, -capSize.Height, 0, 0); 
					lineCapPath.AddLine(0, 0, -capSize.Width / 2, -capSize.Height);
 					lineCapPath.AddLine(-capSize.Width / 2, -capSize.Height, 0, -capSize.Height + arcRadius);
					lineCapPath.AddLine(0, -capSize.Height + arcRadius, capSize.Width / 2, -capSize.Height);
					capinset = capSize.Height - arcRadius; 
					break;
 
 				case LineAnchor.Diamond: 
				case LineAnchor.DiamondAnchor:
 					lineCapPath.AddLine(0, -capSize.Height, capSize.Width / 2, -capSize.Height / 2); 
 					lineCapPath.AddLine(capSize.Width / 2, -capSize.Height / 2, 0, 0);
					lineCapPath.AddLine(0, 0, -capSize.Width / 2, -capSize.Height / 2);
 					lineCapPath.AddLine(-capSize.Width / 2, -capSize.Height / 2, 0, -capSize.Height);
					break; 

				case LineAnchor.Round: 
				case LineAnchor.RoundAnchor: 
 					lineCapPath.AddEllipse(new Rectangle(-capSize.Width / 2, -capSize.Height, capSize.Width, capSize.Height));
					break; 

 				case LineAnchor.Rectangle:
 				case LineAnchor.RectangleAnchor:
					lineCapPath.AddRectangle(new Rectangle(-capSize.Width / 2, -capSize.Height, capSize.Width, capSize.Height)); 
 					break;
 
				case LineAnchor.RoundedRectangle: 
				case LineAnchor.RoundedRectangleAnchor:
					arcRadius = capSize.Height / 4; 
 					lineCapPath.AddPath(GetRoundedRectanglePath(new Rectangle(-capSize.Width / 2, -capSize.Height, capSize.Width, capSize.Height), arcRadius), true);
					break;
 			}
 
 			lineCapPath.CloseFigure();
			return lineCapPath; 
 		} 

        ///  
        /// Get the rounded rectangle path with specified radius
        /// 
        /// Bounding rectangle used for getting the rounded rectangular path
        /// Radius used to obtain the rounded rectangle path 
        /// 
		public static GraphicsPath GetRoundedRectanglePath(Rectangle rectangle, int radius) 
		{ 
			if (rectangle.IsEmpty)
 				throw new ArgumentException(SR.GetString(SR.Error_EmptyRectangleValue), "rectangle"); 

			if (radius <= 0)
 				throw new ArgumentException(SR.GetString(SR.Error_InvalidRadiusValue), "radius");
 
 			int diameter = radius * 2;
 
			GraphicsPath roundedRectangle = new GraphicsPath(); 
 			roundedRectangle.AddLine(rectangle.Left, rectangle.Bottom - radius, rectangle.Left, rectangle.Top + radius);
			roundedRectangle.AddArc(rectangle.Left, rectangle.Top, diameter, diameter, 180.0f, 90.0f); 
			roundedRectangle.AddLine(rectangle.Left + radius, rectangle.Top, rectangle.Right - radius, rectangle.Top);
			roundedRectangle.AddArc(rectangle.Right - diameter, rectangle.Top, diameter, diameter, 270.0f, 90.0f);
 			roundedRectangle.AddLine(rectangle.Right, rectangle.Top + radius, rectangle.Right, rectangle.Bottom - radius);
			roundedRectangle.AddArc(rectangle.Right - diameter, rectangle.Bottom - diameter, diameter, diameter, 0.0f, 90.0f); 
 			roundedRectangle.AddLine(rectangle.Right - radius, rectangle.Bottom, rectangle.Left + radius, rectangle.Bottom);
 			roundedRectangle.AddArc(rectangle.Left, rectangle.Bottom - diameter, diameter, diameter, 90.0f, 90.0f); 
			roundedRectangle.CloseFigure(); 
 			return roundedRectangle;
		} 

        internal static GraphicsPath GetScrollIndicatorPath(Rectangle bounds, ScrollButton button)
        {
            GraphicsPath scrollIndicatorPath = new GraphicsPath(); 

            if (!bounds.IsEmpty) 
            { 
                if (button == ScrollButton.Left || button == ScrollButton.Right)
                { 
                    int arrowHeight = bounds.Height + bounds.Height % 2;
                    int midPoint = arrowHeight / 2;
                    Size arrowSize = new Size(arrowHeight / 2, arrowHeight);
 
                    if (button == ScrollButton.Right)
                    { 
                        scrollIndicatorPath.AddLine(bounds.Left + (bounds.Width - arrowSize.Width) / 2, bounds.Top, bounds.Left + (bounds.Width - arrowSize.Width) / 2, bounds.Top + arrowSize.Height); 
                        scrollIndicatorPath.AddLine(bounds.Left + (bounds.Width - arrowSize.Width) / 2, bounds.Top + arrowSize.Height, bounds.Left + (bounds.Width - arrowSize.Width) / 2 + arrowSize.Width, bounds.Top + midPoint);
                        scrollIndicatorPath.AddLine(bounds.Left + (bounds.Width - arrowSize.Width) / 2 + arrowSize.Width, bounds.Top + midPoint, bounds.Left + (bounds.Width - arrowSize.Width) / 2, bounds.Top); 
                    }
                    else
                    {
                        scrollIndicatorPath.AddLine(bounds.Left + (bounds.Width - arrowSize.Width) / 2, bounds.Top + midPoint, bounds.Left + (bounds.Width - arrowSize.Width) / 2 + arrowSize.Width, bounds.Top + arrowSize.Height); 
                        scrollIndicatorPath.AddLine(bounds.Left + (bounds.Width - arrowSize.Width) / 2 + arrowSize.Width, bounds.Top + arrowSize.Height, bounds.Left + (bounds.Width - arrowSize.Width) / 2 + arrowSize.Width, bounds.Top);
                        scrollIndicatorPath.AddLine(bounds.Left + (bounds.Width - arrowSize.Width) / 2 + arrowSize.Width, bounds.Top, bounds.Left + (bounds.Width - arrowSize.Width) / 2, bounds.Top + midPoint); 
                    } 
                }
                else if (button == ScrollButton.Up || button == ScrollButton.Down) 
                {
                    int arrowWidth = bounds.Width + bounds.Width % 2;
                    int midPoint = arrowWidth / 2;
                    Size arrowSize = new Size(arrowWidth, arrowWidth / 2); 

                    if (button == ScrollButton.Down) 
                    { 
                        scrollIndicatorPath.AddLine(bounds.Left, bounds.Top + (bounds.Height - arrowSize.Height) / 2, bounds.Left + arrowSize.Width, bounds.Top + (bounds.Height - arrowSize.Height) / 2);
                        scrollIndicatorPath.AddLine(bounds.Left + arrowSize.Width, bounds.Top + (bounds.Height - arrowSize.Height) / 2, bounds.Left + midPoint, bounds.Top + (bounds.Height - arrowSize.Height) / 2 + arrowSize.Height); 
                        scrollIndicatorPath.AddLine(bounds.Left + midPoint, bounds.Top + (bounds.Height - arrowSize.Height) / 2 + arrowSize.Height, bounds.Left, bounds.Top + (bounds.Height - arrowSize.Height) / 2);
                    }
                    else
                    { 
                        scrollIndicatorPath.AddLine(bounds.Left + midPoint, bounds.Top + (bounds.Height - arrowSize.Height) / 2, bounds.Left + arrowSize.Width, bounds.Top + (bounds.Height - arrowSize.Height) / 2 + arrowSize.Height);
                        scrollIndicatorPath.AddLine(bounds.Left + arrowSize.Width, bounds.Top + (bounds.Height - arrowSize.Height) / 2 + arrowSize.Height, bounds.Left, bounds.Top + (bounds.Height - arrowSize.Height) / 2 + arrowSize.Height); 
                        scrollIndicatorPath.AddLine(bounds.Left, bounds.Top + (bounds.Height - arrowSize.Height) / 2 + arrowSize.Height, bounds.Left + midPoint, bounds.Top + (bounds.Height - arrowSize.Height) / 2); 
                    }
                } 
            }

            scrollIndicatorPath.CloseFigure();
            return scrollIndicatorPath; 
        }
 
		internal static GraphicsPath[] GetPagePaths(Rectangle pageBounds, int pageFoldSize, DesignerContentAlignment foldAlignment) 
        {
            GraphicsPath[] pagePaths = new GraphicsPath[2]; 

			if (foldAlignment == DesignerContentAlignment.TopLeft)
            {
                //Page path 
                pagePaths[0] = new GraphicsPath();
                pagePaths[0].AddLine(pageBounds.Left, pageBounds.Top + pageFoldSize, pageBounds.Left + pageFoldSize, pageBounds.Top + pageFoldSize); 
                pagePaths[0].AddLine(pageBounds.Left + pageFoldSize, pageBounds.Top + pageFoldSize, pageBounds.Left + pageFoldSize, pageBounds.Top); 
                pagePaths[0].AddLine(pageBounds.Left + pageFoldSize, pageBounds.Top, pageBounds.Right, pageBounds.Top);
                pagePaths[0].AddLine(pageBounds.Right, pageBounds.Top, pageBounds.Right, pageBounds.Bottom); 
                pagePaths[0].AddLine(pageBounds.Right, pageBounds.Bottom, pageBounds.Left, pageBounds.Bottom);
                pagePaths[0].AddLine(pageBounds.Left, pageBounds.Bottom, pageBounds.Left, pageBounds.Top + pageFoldSize);

                //Page fold path 
                pagePaths[1] = new GraphicsPath();
                pagePaths[1].AddLine(pageBounds.Left, pageBounds.Top + pageFoldSize, pageBounds.Left + pageFoldSize, pageBounds.Top + pageFoldSize); 
                pagePaths[1].AddLine(pageBounds.Left + pageFoldSize, pageBounds.Top + pageFoldSize, pageBounds.Left + pageFoldSize, pageBounds.Top); 
                pagePaths[1].AddLine(pageBounds.Left + pageFoldSize, pageBounds.Top, pageBounds.Left, pageBounds.Top + pageFoldSize);
            } 
 			else if (foldAlignment == DesignerContentAlignment.BottomLeft)
            {
                //Page path
                pagePaths[0] = new GraphicsPath(); 
                pagePaths[0].AddLine(pageBounds.Left, pageBounds.Top, pageBounds.Right, pageBounds.Top);
                pagePaths[0].AddLine(pageBounds.Right, pageBounds.Top, pageBounds.Right, pageBounds.Bottom); 
                pagePaths[0].AddLine(pageBounds.Right, pageBounds.Bottom, pageBounds.Left + pageFoldSize, pageBounds.Bottom); 
                pagePaths[0].AddLine(pageBounds.Left + pageFoldSize, pageBounds.Bottom, pageBounds.Left + pageFoldSize, pageBounds.Bottom - pageFoldSize);
                pagePaths[0].AddLine(pageBounds.Left + pageFoldSize, pageBounds.Bottom - pageFoldSize, pageBounds.Left, pageBounds.Bottom - pageFoldSize); 
                pagePaths[0].AddLine(pageBounds.Left, pageBounds.Bottom - pageFoldSize, pageBounds.Left, pageBounds.Top);

                //Page fold path
                pagePaths[1] = new GraphicsPath(); 
                pagePaths[1].AddLine(pageBounds.Left + pageFoldSize, pageBounds.Bottom, pageBounds.Left + pageFoldSize, pageBounds.Bottom - pageFoldSize);
                pagePaths[1].AddLine(pageBounds.Left + pageFoldSize, pageBounds.Bottom - pageFoldSize, pageBounds.Left, pageBounds.Bottom - pageFoldSize); 
                pagePaths[1].AddLine(pageBounds.Left, pageBounds.Bottom - pageFoldSize, pageBounds.Left + pageFoldSize, pageBounds.Bottom); 

            } 
			else if (foldAlignment == DesignerContentAlignment.TopRight)
            {
                //Page path
                pagePaths[0] = new GraphicsPath(); 
                pagePaths[0].AddLine(pageBounds.Left, pageBounds.Top, pageBounds.Right - pageFoldSize, pageBounds.Top);
                pagePaths[0].AddLine(pageBounds.Right - pageFoldSize, pageBounds.Top, pageBounds.Right - pageFoldSize, pageBounds.Top + pageFoldSize); 
                pagePaths[0].AddLine(pageBounds.Right - pageFoldSize, pageBounds.Top + pageFoldSize, pageBounds.Right, pageBounds.Top + pageFoldSize); 
                pagePaths[0].AddLine(pageBounds.Right, pageBounds.Top + pageFoldSize, pageBounds.Right, pageBounds.Bottom);
                pagePaths[0].AddLine(pageBounds.Right, pageBounds.Bottom, pageBounds.Left, pageBounds.Bottom); 
                pagePaths[0].AddLine(pageBounds.Left, pageBounds.Bottom, pageBounds.Left, pageBounds.Top);

                //Page fold path
                pagePaths[1] = new GraphicsPath(); 
                pagePaths[1].AddLine(pageBounds.Right - pageFoldSize, pageBounds.Top, pageBounds.Right - pageFoldSize, pageBounds.Top + pageFoldSize);
                pagePaths[1].AddLine(pageBounds.Right - pageFoldSize, pageBounds.Top + pageFoldSize, pageBounds.Right, pageBounds.Top + pageFoldSize); 
                pagePaths[1].AddLine(pageBounds.Right, pageBounds.Top + pageFoldSize, pageBounds.Right - pageFoldSize, pageBounds.Top); 
            }
 			else if (foldAlignment == DesignerContentAlignment.BottomRight) 
            {
                //Page path
                pagePaths[0] = new GraphicsPath();
                pagePaths[0].AddLine(pageBounds.Left, pageBounds.Top, pageBounds.Right, pageBounds.Top); 
                pagePaths[0].AddLine(pageBounds.Right, pageBounds.Top, pageBounds.Right, pageBounds.Bottom - pageFoldSize);
                pagePaths[0].AddLine(pageBounds.Right, pageBounds.Bottom - pageFoldSize, pageBounds.Right - pageFoldSize, pageBounds.Bottom - pageFoldSize); 
                pagePaths[0].AddLine(pageBounds.Right - pageFoldSize, pageBounds.Bottom - pageFoldSize, pageBounds.Right - pageFoldSize, pageBounds.Bottom); 
                pagePaths[0].AddLine(pageBounds.Right - pageFoldSize, pageBounds.Bottom, pageBounds.Left, pageBounds.Bottom);
                pagePaths[0].AddLine(pageBounds.Left, pageBounds.Bottom, pageBounds.Left, pageBounds.Top); 

                //Page fold path
                pagePaths[1] = new GraphicsPath();
                pagePaths[1].AddLine(pageBounds.Right, pageBounds.Bottom - pageFoldSize, pageBounds.Right - pageFoldSize, pageBounds.Bottom - pageFoldSize); 
                pagePaths[1].AddLine(pageBounds.Right - pageFoldSize, pageBounds.Bottom - pageFoldSize, pageBounds.Right - pageFoldSize, pageBounds.Bottom);
                pagePaths[1].AddLine(pageBounds.Right - pageFoldSize, pageBounds.Bottom, pageBounds.Right, pageBounds.Bottom - pageFoldSize); 
            } 

            return pagePaths; 
        }
        #endregion
 		#endregion
 
		#region Native Drawing Calls
 
 		#region Class Hdc 
		private sealed class Hdc : IDisposable
		{ 
			private Graphics graphics;
 			private HandleRef hdc;
			private HandleRef oldPen;
 			private HandleRef oldPenEx; 
 			private HandleRef oldBrush;
			private int oldGraphicsMode = 0; 
 
 			internal Hdc(Graphics graphics)
			{ 
				this.graphics = graphics;

				NativeMethods.XFORM xform = new NativeMethods.XFORM(this.graphics.Transform);
 
 				this.hdc = new HandleRef(this, this.graphics.GetHdc());
 
                //If the function fails, the return value is zero 
				this.oldGraphicsMode = NativeMethods.SetGraphicsMode(this.hdc, NativeMethods.GM_ADVANCED);
                if (this.oldGraphicsMode == 0) 
                    throw new Win32Exception(Marshal.GetLastWin32Error());

                //If the function fails, the return value is zero.
                int result = NativeMethods.SetWorldTransform(this.hdc, xform); 
                if (result == 0)
                    throw new Win32Exception(Marshal.GetLastWin32Error()); 
 
                IntPtr handle = NativeMethods.GetCurrentObject(this.hdc, NativeMethods.OBJ_PEN);
                if (handle == IntPtr.Zero) 
                    throw new Win32Exception(Marshal.GetLastWin32Error());

                this.oldPen = new HandleRef(this, handle);
 
                handle = NativeMethods.GetCurrentObject(this.hdc, NativeMethods.OBJ_EXTPEN);
                if (handle == IntPtr.Zero) 
                    throw new Win32Exception(Marshal.GetLastWin32Error()); 

                this.oldPenEx = new HandleRef(this, handle); 

                handle = NativeMethods.GetCurrentObject(this.hdc, NativeMethods.OBJ_BRUSH);
                if (handle == IntPtr.Zero)
                    throw new Win32Exception(Marshal.GetLastWin32Error()); 

                this.oldBrush = new HandleRef(this, handle); 
 			} 

 			void IDisposable.Dispose() 
			{
 				if (this.graphics != null)
				{
                    string msg; 
					IntPtr objectPtr = NativeMethods.SelectObject(this.hdc, this.oldPen);
					if (objectPtr == IntPtr.Zero) 
 					{ 
						Win32Exception e = new Win32Exception();
                        msg = e.Message; 
 						Debug.Assert(false, msg);
 					}

					objectPtr = NativeMethods.SelectObject(this.hdc, this.oldPenEx); 
 					if (objectPtr == IntPtr.Zero)
					{ 
						Win32Exception e = new Win32Exception(); 
                        msg = e.Message;
						Debug.Assert(false, msg); 
 					}

					objectPtr = NativeMethods.SelectObject(this.hdc, this.oldBrush);
 					if (objectPtr == IntPtr.Zero) 
 					{
						Win32Exception e = new Win32Exception(); 
                        msg = e.Message; 
 						Debug.Assert(false, msg);
					} 

					int result = NativeMethods.SetWorldTransform(this.hdc, new NativeMethods.XFORM());
					if (result == 0)
 					{ 
						Win32Exception e = new Win32Exception();
                        msg = e.Message; 
 						Debug.Assert(false, msg); 
 					}
 
                    result = NativeMethods.SetGraphicsMode(this.hdc, this.oldGraphicsMode);
					if (result == 0)
 					{
						Win32Exception e = new Win32Exception(); 
                        msg = e.Message;
						Debug.Assert(false, msg); 
					} 

 					this.graphics.ReleaseHdc(); 
					this.graphics = null;
 				}
 			}
 
            //internal void DrawLines(HPen pen, Point[] points)
            //{ 
            //    try 
            //    {
            //        IntPtr objectPtr = NativeMethods.SelectObject(this.hdc, pen.Handle); 
            //        if (objectPtr == IntPtr.Zero)
            //            throw new Win32Exception(Marshal.GetLastWin32Error());

            //        if (!NativeMethods.MoveToEx(this.hdc, points[0].X, points[0].Y, null)) 
            //            throw new Win32Exception(Marshal.GetLastWin32Error());
 
            //        for (int i = 0; i < points.Length - 1; i++) 
            //        {
            //            if (!NativeMethods.LineTo(this.hdc, points[i + 1].X, points[i + 1].Y)) 
            //                throw new Win32Exception(Marshal.GetLastWin32Error());
            //        }
            //    }
            //    finally 
            //    {
            //        IntPtr objectPtr = NativeMethods.SelectObject(this.hdc, this.oldPen); 
            //        if (objectPtr == IntPtr.Zero) 
            //            throw new Win32Exception(Marshal.GetLastWin32Error());
            //    } 
            //}

			internal void DrawGrid(HPen majorGridPen, HPen minorGridPen, Rectangle viewableRectangle, Size gridUnit, bool showMinorGrid)
 			{ 
				try
				{ 
					Point gridStart = Point.Empty; 
 					gridStart.X = viewableRectangle.X - (viewableRectangle.X % gridUnit.Width);
					gridStart.Y = viewableRectangle.Y - (viewableRectangle.Y % gridUnit.Height); 
 					IntPtr objectPtr = NativeMethods.SelectObject(this.hdc, majorGridPen.Handle);
                    if (objectPtr == IntPtr.Zero)
                        throw new Win32Exception(Marshal.GetLastWin32Error());
 
 					for (int gridCoOrd = gridStart.X; gridCoOrd <= viewableRectangle.Right; gridCoOrd += Math.Max(gridUnit.Width, 1))
					{ 
 						if (gridCoOrd >= viewableRectangle.Left) 
						{
							if (!NativeMethods.MoveToEx(this.hdc, gridCoOrd, viewableRectangle.Top + 1, null)) 
                                throw new Win32Exception(Marshal.GetLastWin32Error());

							if (!NativeMethods.LineTo(this.hdc, gridCoOrd, viewableRectangle.Bottom - 1))
                                throw new Win32Exception(Marshal.GetLastWin32Error()); 
 						}
 
						if (showMinorGrid && (gridCoOrd + gridUnit.Width / 2) >= viewableRectangle.Left && (gridCoOrd + gridUnit.Width / 2) <= viewableRectangle.Right) 
 						{
 							objectPtr = NativeMethods.SelectObject(this.hdc, minorGridPen.Handle); 
                            if (objectPtr == IntPtr.Zero)
                                throw new Win32Exception(Marshal.GetLastWin32Error());

							if (!NativeMethods.MoveToEx(this.hdc, gridCoOrd + gridUnit.Width / 2, viewableRectangle.Top + 1, null)) 
                                throw new Win32Exception(Marshal.GetLastWin32Error());
 
 							if (!NativeMethods.LineTo(this.hdc, gridCoOrd + gridUnit.Width / 2, viewableRectangle.Bottom - 1)) 
                                throw new Win32Exception(Marshal.GetLastWin32Error());
 
							objectPtr = NativeMethods.SelectObject(this.hdc, majorGridPen.Handle);
                            if (objectPtr == IntPtr.Zero)
                                throw new Win32Exception(Marshal.GetLastWin32Error());
                        } 
					}
 
					for (int gridCoOrd = gridStart.Y; gridCoOrd <= viewableRectangle.Bottom; gridCoOrd += Math.Max(gridUnit.Height, 1)) 
 					{
						if (gridCoOrd >= viewableRectangle.Top) 
 						{
 							if (!NativeMethods.MoveToEx(this.hdc, viewableRectangle.Left + 1, gridCoOrd, null))
                                throw new Win32Exception(Marshal.GetLastWin32Error());
 
							if (!NativeMethods.LineTo(this.hdc, viewableRectangle.Right - 1, gridCoOrd))
                                throw new Win32Exception(Marshal.GetLastWin32Error()); 
 						} 

						if (showMinorGrid && (gridCoOrd + gridUnit.Height / 2) >= viewableRectangle.Top && (gridCoOrd + gridUnit.Height / 2) <= viewableRectangle.Bottom) 
						{
							objectPtr =  NativeMethods.SelectObject(this.hdc, minorGridPen.Handle);
                            if (objectPtr == IntPtr.Zero)
                                throw new Win32Exception(Marshal.GetLastWin32Error()); 

 							if (!NativeMethods.MoveToEx(this.hdc, viewableRectangle.Left + 1, gridCoOrd + gridUnit.Height / 2, null)) 
                                throw new Win32Exception(Marshal.GetLastWin32Error()); 

							if (!NativeMethods.LineTo(this.hdc, viewableRectangle.Right - 1, gridCoOrd + gridUnit.Height / 2)) 
                                throw new Win32Exception(Marshal.GetLastWin32Error());

 							objectPtr = NativeMethods.SelectObject(this.hdc, majorGridPen.Handle);
                            if (objectPtr == IntPtr.Zero) 
                                throw new Win32Exception(Marshal.GetLastWin32Error());
 
 						} 
					}
 				} 
				finally
				{
					IntPtr objectPtr = NativeMethods.SelectObject(this.hdc, this.oldPen);
                    if (objectPtr == IntPtr.Zero) 
                        throw new Win32Exception(Marshal.GetLastWin32Error());
 
 				} 
			}
 		} 
 		#endregion

		#region Class HPen
 		private sealed class HPen : IDisposable 
		{
			private Pen pen; 
			private HandleRef hpen; 

 			internal HPen(Pen pen) 
			{
 				this.pen = pen;
 				int penStyle = ((int)pen.DashStyle < 4) ? (int)pen.DashStyle : 0;
                IntPtr penPtr = NativeMethods.ExtCreatePen(NativeMethods.PS_COSMETIC | NativeMethods.PS_USERSTYLE | penStyle, 1, new NativeMethods.LOGBRUSH(NativeMethods.BS_SOLID, ColorTranslator.ToWin32(pen.Color), 0), 2, new int[] { 1, 1 }); 
                if (penPtr == IntPtr.Zero)
                    throw new Win32Exception(Marshal.GetLastWin32Error()); 
 
                this.hpen = new HandleRef(this, penPtr);
 
			}

 			void IDisposable.Dispose()
			{ 
				if (this.pen != null)
				{ 
                    //If the function succeeds, the return value is nonzero 
                    int result = NativeMethods.DeleteObject(this.hpen);
 					if (result == 0) 
					{
 						Win32Exception e = new Win32Exception();
                        string msg = e.Message;
 						Debug.Assert(false, msg); 
					}
 
 					this.pen = null; 
				}
			} 

			internal HandleRef Handle
 			{
				get 
 				{
 					return this.hpen; 
				} 
 			}
 
            //internal DashStyle Style
            //{
            //    get
            //    { 
            //        return this.pen.DashStyle;
            //    } 
            //} 
		}
		#endregion 

		#endregion
 	}
	#endregion 

 	internal static class UnsafeNativeMethods 
 	{ 
		internal const int S_OK = 0x00000000;
 		internal const int S_FALSE = 0x00000001; 

		internal static readonly int GWL_EXSTYLE = (-20);
		internal static readonly int WS_EX_LAYOUTRTL = 0x400000;
 
		[DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)]
 		internal static extern int GetWindowLong(IntPtr hWnd, int nIndex); 
	} 

    internal static class DesignerHelpers 
    {
 		private static readonly string WorkflowDesignerSubKey = "Workflow Designer";
        internal const string DeclarativeRulesRef = "System.Workflow.Activities.Rules.RuleConditionReference, " + AssemblyRef.ActivitiesAssemblyRef;
        internal const string SequentialWorkflowTypeRef = "System.Workflow.Activities.SequentialWorkflowActivity, " + AssemblyRef.ActivitiesAssemblyRef; 
        internal const string StateMachineWorkflowTypeRef = "System.Workflow.Activities.StateMachineWorkflowActivity, " + AssemblyRef.ActivitiesAssemblyRef;
        internal const string EventHandlersTypeRef = "System.Workflow.Activities.EventHandlersActivity, " + AssemblyRef.ActivitiesAssemblyRef; 
        internal const string IfElseBranchTypeRef = "System.Workflow.Activities.IfElseBranchActivity, " + AssemblyRef.ActivitiesAssemblyRef; 
        internal const string CodeActivityTypeRef = "System.Workflow.Activities.CodeActivity, " + AssemblyRef.ActivitiesAssemblyRef;
 
        internal static Point SnapToGrid(Point location)
        {
            AmbientTheme ambientTheme = WorkflowTheme.CurrentTheme.AmbientTheme;
            if (ambientTheme.ShowGrid) 
            {
                Size snapSize = WorkflowTheme.CurrentTheme.AmbientTheme.GridSize; 
                snapSize.Width /= 2; snapSize.Height /= 2; 
                location.X = ((location.X / snapSize.Width) * snapSize.Width) + (((location.X % snapSize.Width) > snapSize.Width / 2) ? snapSize.Width : 0);
                location.Y = ((location.Y / snapSize.Height) * snapSize.Height) + (((location.Y % snapSize.Height) > snapSize.Height / 2) ? snapSize.Height : 0); 
            }
            return location;
        }
 
 		internal static string DesignerPerUserRegistryKey
		{ 
 			get 
			{
				return Helpers.PerUserRegistryKey + "\\" + DesignerHelpers.WorkflowDesignerSubKey; 
			}
 		}

		internal static bool AreAssociatedDesignersMovable(ICollection components) 
 		{
 			foreach (object obj in components) 
			{ 
                Activity activity = obj as Activity;
                if (activity == null) 
                {
                    HitTestInfo hitInfo = obj as HitTestInfo;
                    activity = (hitInfo != null && hitInfo.AssociatedDesigner != null) ? hitInfo.AssociatedDesigner.Activity : null;
                } 

                ActivityDesigner designer = ActivityDesigner.GetDesigner(activity); 
                if (designer != null && designer.IsLocked) 
                    return false;
            } 

            return true;
 		}
 
		internal static Activity GetNextSelectableActivity(Activity currentActivity)
		{ 
            ActivityDesigner activityDesigner = ActivityDesigner.GetDesigner(currentActivity); 
            CompositeActivityDesigner parentDesigner = (activityDesigner != null) ? activityDesigner.ParentDesigner : null;
            if (parentDesigner == null) 
				return null;

 			DesignerNavigationDirection navigation = (parentDesigner is ParallelActivityDesigner || parentDesigner is ActivityPreviewDesigner) ? DesignerNavigationDirection.Right : DesignerNavigationDirection.Down;
			Activity nextSelectableActivity = null; 
 			object nextSelectableObject = parentDesigner.GetNextSelectableObject(currentActivity, navigation);
            while (nextSelectableActivity == null && nextSelectableObject != null && nextSelectableObject != currentActivity) 
            { 
 				nextSelectableActivity = nextSelectableObject as Activity;
				nextSelectableObject = parentDesigner.GetNextSelectableObject(nextSelectableObject, navigation); 
 			}

            if (nextSelectableActivity == null)
            { 
				navigation = (parentDesigner is ParallelActivityDesigner || parentDesigner is ActivityPreviewDesigner) ? DesignerNavigationDirection.Left : DesignerNavigationDirection.Up;
				nextSelectableObject = parentDesigner.GetNextSelectableObject(currentActivity, navigation); 
                while (nextSelectableActivity == null && nextSelectableObject != null && nextSelectableObject != currentActivity) 
                {
					nextSelectableActivity = nextSelectableObject as Activity; 
 					nextSelectableObject = parentDesigner.GetNextSelectableObject(nextSelectableObject, navigation);
				}
 			}
 
 			if (nextSelectableActivity == null)
				nextSelectableActivity = parentDesigner.Activity; 
 
 			return nextSelectableActivity;
		} 

		internal static void SerializeDesignerStates(IDesignerHost designerHost, BinaryWriter writer)
		{
 			writer.Write(designerHost.Container.Components.Count); 
			foreach (IComponent component in designerHost.Container.Components)
 			{ 
 				// write activity identifier 
				writer.Write(component.Site.Name);
 
 				//placeholder for length
				int activityDataLengthPosition = (int)writer.BaseStream.Length;

				writer.Write((int)0); 

				ActivityDesigner designer = designerHost.GetDesigner(component) as ActivityDesigner; 
 
 				if (designer != null)
				{ 
 					int activityDataPosition = (int)writer.BaseStream.Length;

 					// write activity data
					((IPersistUIState)designer).SaveViewState(writer); 

 					// place length 
					writer.Seek(activityDataLengthPosition, SeekOrigin.Begin); 
					writer.Write((int)writer.BaseStream.Length - activityDataPosition);
					writer.Seek(0, SeekOrigin.End); 
 				}
			}
 		}
 
 		internal static bool DeserializeDesignerStates(IDesignerHost designerHost, BinaryReader reader)
		{ 
 			int componentCount = reader.ReadInt32(); 
			bool outdated = (componentCount != designerHost.Container.Components.Count);
 
			for (int loop = 0; loop < componentCount; loop++)
			{
 				string componentName = reader.ReadString();
				int length = reader.ReadInt32(); 

 				if (designerHost.Container.Components[componentName] != null) 
 				{ 
					ActivityDesigner designer = designerHost.GetDesigner(designerHost.Container.Components[componentName]) as ActivityDesigner;
 
 					if (designer != null)
					{
						((IPersistUIState)designer).LoadViewState(reader);
					} 
 					else
					{ 
 						outdated = true; 
 						reader.BaseStream.Position += length; // skip activity data
					} 

 				}
				else
				{ 
					outdated = true;
 					reader.BaseStream.Position += length; // skip activity data 
				} 
 			}
 
 			return outdated;
		}

        internal static void MakePropertiesReadOnly(IServiceProvider serviceProvider, object topComponent) 
        {
            Hashtable visitedComponents = new Hashtable(); 
            Queue nestedComponents = new Queue(); 
            nestedComponents.Enqueue(topComponent);
 
            while (nestedComponents.Count > 0)
            {
                object component = nestedComponents.Dequeue();
                if (visitedComponents[component.GetHashCode()] == null) 
                {
                    visitedComponents[component.GetHashCode()] = component; 
 
                    //add custom readonly type descriptor to the component (to set ForceReadonly flag in the property grid)
                    TypeDescriptor.AddProvider(new ReadonlyTypeDescriptonProvider(TypeDescriptor.GetProvider(component)), component); 

                    //now go through all the properties and add custom readonly type descriptor to all composite ones
                    PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(component, new Attribute[] { BrowsableAttribute.Yes });
                    foreach (PropertyDescriptor property in properties) 
                    {
                        if (!property.PropertyType.IsPrimitive) 
                        { 
                            object component1 = property.GetValue(component);
                            if (component1 != null) 
                            {
                                TypeConverter converter = TypeDescriptor.GetConverter(component1);
                                TypeDescriptorContext context = new TypeDescriptorContext(serviceProvider, property, component);
                                if (converter.GetPropertiesSupported(context)) 
                                {
                                    TypeDescriptor.AddProvider(new ReadonlyTypeDescriptonProvider(TypeDescriptor.GetProvider(component1)), component1); 
                                    nestedComponents.Enqueue(component1); 
                                }
                            } 
                        }
                    }
                }
            } 
        }
 
 		internal static void UpdateSiteName(Activity activity, string newID) 
		{
            if (activity == null) 
                throw new ArgumentException("activity");

            string name = newID;
            if (Helpers.IsActivityLocked(activity)) 
                name = InternalHelpers.GenerateQualifiedNameForLockedActivity(activity, newID);
			((IComponent)activity).Site.Name = name; 
 
			// If this activity is a custom composite activity, we also need to update the site name
 			// for all locked children. 
			if (activity is CompositeActivity)
 			{
 				foreach (Activity childActivity in Helpers.GetNestedActivities(activity as CompositeActivity))
				{ 
                    if (Helpers.IsActivityLocked(childActivity))
 					{ 
                        Activity declaringActivity = Helpers.GetDeclaringActivity(childActivity); 
                        ((IComponent)childActivity).Site.Name = ((IComponent)declaringActivity).Site.Name + "." + childActivity.Name;//the parent should have already been updated by now
					} 
				}
			}
 		}
 
        internal static DialogResult ShowMessage(IServiceProvider serviceProvider, string message, string title, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton)
        { 
            IWin32Window owner = null; 

            IUIService uiService = serviceProvider.GetService(typeof(IUIService)) as IUIService; 
            if (uiService != null)
                owner = uiService.GetDialogOwnerWindow();
            else
                owner = Form.ActiveForm as IWin32Window; 

			Control control = owner as Control; 
 			MessageBoxOptions options = 0; 

 			if (owner != null) 
			{
 				if (control != null)
				{
					options = (control.RightToLeft == RightToLeft.Yes) ? MessageBoxOptions.RightAlign & MessageBoxOptions.RtlReading : 0; 
				}
 				else if(owner.Handle != IntPtr.Zero) 
				{ 
 					int style = UnsafeNativeMethods.GetWindowLong(owner.Handle, UnsafeNativeMethods.GWL_EXSTYLE);
 					int hr = Marshal.GetLastWin32Error(); 
					if (hr == UnsafeNativeMethods.S_OK && (style & UnsafeNativeMethods.WS_EX_LAYOUTRTL) == UnsafeNativeMethods.WS_EX_LAYOUTRTL)
 						options = MessageBoxOptions.RightAlign & MessageBoxOptions.RtlReading;
				}
 
				return MessageBox.Show(owner, message, title, buttons, icon, defaultButton, options);
			} 
 			else 
			{
 				return MessageBox.Show(message, title, buttons, icon, defaultButton, options); 
 			}
        }

		internal static void ShowHelpFromKeyword(IServiceProvider serviceProvider, string helpKeyword) 
 		{
			IHelpService helpService = serviceProvider.GetService(typeof(IHelpService)) as IHelpService; 
			if (helpService != null) 
			{
 				helpService.ShowHelpFromKeyword(helpKeyword); 
				return;
 			}

 			DesignerHelpers.ShowError(serviceProvider, DR.GetString(DR.NoHelpAvailable)); 
		}
 
        internal static void ShowError(IServiceProvider serviceProvider, string message) 
        {
            ShowMessage(serviceProvider, message, DR.GetString(DR.WorkflowDesignerTitle), MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); 
        }

        internal static void ShowError(IServiceProvider serviceProvider, Exception e)
        { 
            if (e == CheckoutException.Canceled)
                return; 
 
            while (e is TargetInvocationException && e.InnerException != null)
                e = e.InnerException; 

            string message = e.Message;
            if (message == null || message.Length == 0)
                message = e.ToString(); 

            ShowMessage(serviceProvider, message, DR.GetString(DR.WorkflowDesignerTitle), MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); 
        } 

        internal static bool IsValidImageResource(DesignerTheme designerTheme, string directory, string path) 
        {
            Image image = GetImageFromPath(designerTheme, directory, path);
            bool validImage = (image != null);
            if (image != null) 
                image.Dispose();
            return validImage; 
        } 

 		internal static string GetRelativePath(string pathFrom, string pathTo) 
		{
			Uri uri = new Uri(pathFrom);
			string relativePath = Uri.UnescapeDataString(uri.MakeRelativeUri(new Uri(pathTo)).ToString());
 			relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); 
			if (!relativePath.Contains(Path.DirectorySeparatorChar.ToString()))
 				relativePath = "." + Path.DirectorySeparatorChar + relativePath; 
 			return relativePath; 
		}
 
 		internal static Image GetImageFromPath(DesignerTheme designerTheme, string directory, string path)
		{
			Bitmap image = null;
			if (path.Contains(Path.DirectorySeparatorChar.ToString()) && directory.Length > 0) 
 			{
				string imageFilePath = Uri.UnescapeDataString((new Uri(new Uri(directory), path).LocalPath));				 
 				if (File.Exists(imageFilePath)) 
 				{
					try 
 					{
						image = new Bitmap(imageFilePath);
					}
					catch 
 					{
					} 
 				} 
 			}
			else if (designerTheme.DesignerType != null) 
 			{
				int index = path.LastIndexOf('.');
				if (index > 0)
				{ 
 					string nameSpace = path.Substring(0, index);
					string name = path.Substring(index + 1); 
 					if (nameSpace != null && nameSpace.Length > 0 && 
 						name != null && name.Length > 0)
					{ 
 						try
						{
							ResourceManager resourceManager = new ResourceManager(nameSpace, designerTheme.DesignerType.Assembly);
							image = resourceManager.GetObject(name) as Bitmap; 
 						}
						catch 
 						{ 
 						}
					} 
 				}
			}

            if (image != null) 
                image.MakeTransparent(AmbientTheme.TransparentColor);
 
            return image; 
		}
 
        private static bool ShowingMenu = false;

        internal static DesignerVerb[] GetDesignerActionVerbs(ActivityDesigner designer, ReadOnlyCollection designerActions)
        { 
            List actionVerbs = new List();
 
            for (int i = 0; i < designerActions.Count; i++) 
            {
                DesignerVerb actionVerb = new DesignerVerb(designerActions[i].Text, new EventHandler(new EventHandler(OnExecuteDesignerAction)), new CommandID(WorkflowMenuCommands.MenuGuid, WorkflowMenuCommands.VerbGroupDesignerActions + i)); 
                actionVerb.Properties[DesignerUserDataKeys.DesignerAction] = designerActions[i];
                actionVerb.Properties[DesignerUserDataKeys.Designer] = designer;
                actionVerbs.Add(actionVerb);
            } 

            return actionVerbs.ToArray(); ; 
        } 

		internal static void ShowDesignerVerbs(ActivityDesigner designer, Point location, ICollection designerVerbs) 
        {
            if (ShowingMenu || designerVerbs.Count == 0)
                return;
 
            IMenuCommandService menuCommandService = designer.Activity.Site.GetService(typeof(IMenuCommandService)) as IMenuCommandService;
            if (menuCommandService == null) 
                throw new Exception(SR.GetString(SR.General_MissingService, typeof(IMenuCommandService).FullName)); 

            try 
            {
                foreach (DesignerVerb designerVerb in designerVerbs)
                    menuCommandService.AddCommand(designerVerb);
 
                ShowingMenu = true;
                menuCommandService.ShowContextMenu(WorkflowMenuCommands.DesignerActionsMenu, location.X - 2, location.Y + 1); 
            } 
            finally
            { 
                ShowingMenu = false;
                foreach (DesignerVerb designerVerb in designerVerbs)
                    menuCommandService.RemoveCommand(designerVerb);
            } 
        }
 
        private static void OnExecuteDesignerAction(object sender, EventArgs e) 
        {
            DesignerVerb designerVerb = sender as DesignerVerb; 
            if (designerVerb != null)
            {
                DesignerAction designerAction = designerVerb.Properties[DesignerUserDataKeys.DesignerAction] as DesignerAction;
                if (designerAction != null) 
                {
                    ActivityDesigner designer = designerVerb.Properties[DesignerUserDataKeys.Designer] as ActivityDesigner; 
                    if (designer != null) 
                        designer.OnExecuteDesignerAction(designerAction);
                } 
            }
        }

 		internal static string CreateUniqueMethodName(IComponent component, string propName, Type delegateType) 
		{
 			IServiceProvider serviceProvider = component.Site as IServiceProvider; 
 			if (serviceProvider == null) 
				throw new ArgumentException("component");
 
 			IDesignerHost host = serviceProvider.GetService(typeof(IDesignerHost)) as IDesignerHost;
			if (host == null)
				throw new InvalidOperationException(SR.GetString(SR.General_MissingService, typeof(IDesignerHost).FullName));
 
			ITypeProvider typeProvider = (ITypeProvider)serviceProvider.GetService(typeof(ITypeProvider));
 			if (typeProvider == null) 
				throw new InvalidOperationException(SR.GetString(SR.General_MissingService, typeof(ITypeProvider).FullName)); 

 			string name = null; 
 			IReferenceService referenceService = serviceProvider.GetService(typeof(IReferenceService)) as IReferenceService;
			if (referenceService != null)
 			{
				name = referenceService.GetName(component); 
			}
			else 
 			{ 
				ISite site = ((IComponent)component).Site;
 				if (site != null) 
 					name = site.Name;
			}

 			if (name == null) 
				name = component.GetType().Name;
 
			name = name.Replace('.', '_'); 
			name = name.Replace('/', '_') + "_" + propName;
 			name = name.Replace('(', '_'); 
			name = name.Replace(')', '_');
 			name = name.Replace(" ", "");

 			DelegateTypeInfo dti = new DelegateTypeInfo(delegateType); 

            Activity contextActivity = host.RootComponent as Activity; 
            if (contextActivity == null) 
            {
                Activity activity = component as Activity; 
                throw new InvalidOperationException(SR.GetString(SR.Error_CantCreateMethod, activity != null ? activity.QualifiedName : string.Empty));
            }

			Type type = Helpers.GetDataSourceClass(contextActivity, serviceProvider); 
 			if (type == null)
                throw new InvalidOperationException(SR.GetString(SR.Error_CantCreateMethod, contextActivity.QualifiedName)); 
 
			BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy;
			MethodInfo[] methods = type.GetMethods(bindingFlags); 
			ArrayList compatibleMethods = new ArrayList();

 			foreach (MethodInfo method in methods)
			{ 
 				if (method.GetParameters().Length == dti.Parameters.Length)
 				{ 
					bool match = true; 
 					for (int i = 0; i < dti.Parameters.Length; i++)
					{ 
						ParameterInfo right = method.GetParameters()[i];
						CodeParameterDeclarationExpression left = dti.Parameters[i];

 						FieldDirection direction = left.Direction; 
						if ((direction == FieldDirection.In && !right.IsIn) ||
 							(direction == FieldDirection.Out && !right.IsOut) || 
 							(direction == FieldDirection.Ref && !(right.IsIn && right.IsOut)) || 
							!Helpers.TypesEqual(left.Type, right.ParameterType))
 						{ 
							match = false;
							break;
						}
 					} 
					if (match)
 						compatibleMethods.Add(method.Name); 
 				} 
			}
 
 			int tryCount = 0;
			bool duplicate = true;
			string uniqueName = name;
 
            MemberInfo[] members = type.GetMembers();
 
            while (duplicate && tryCount < Int32.MaxValue) 
			{
 				duplicate = false; 
				foreach (string existingMethod in compatibleMethods)
 				{
                    if (string.Compare(existingMethod, uniqueName, StringComparison.OrdinalIgnoreCase) == 0)
 					{ 
						duplicate = true;
 						break; 
					} 
				}
				if (!duplicate) 
 				{
                    foreach (MemberInfo member in members)
					{
                        if (!(member is MethodInfo) && string.Compare(member.Name, uniqueName, StringComparison.OrdinalIgnoreCase) == 0) 
 						{
 							duplicate = true; 
							break; 
 						}
					} 
				}
				if (!duplicate)
 				{
					MethodInfo mi = host.RootComponent.GetType().GetMethod(uniqueName, bindingFlags, null, dti.ParameterTypes, null); 
 					if (mi != null && !mi.IsPrivate)
 						duplicate = true; 
				} 
 				if (duplicate)
					uniqueName = name + "_" + (++tryCount).ToString(CultureInfo.InvariantCulture); 
			}

			return uniqueName;
 		} 

		internal static string GenerateUniqueIdentifier(IServiceProvider serviceProvider, string baseIdentifier, string[] existingNames) 
 		{ 
            CodeDomProvider provider = null;
            if (serviceProvider != null) 
            {
                provider = serviceProvider.GetService(typeof(CodeDomProvider)) as CodeDomProvider;
                if (provider == null)
                { 
                    IdentifierCreationService identifierCreationService = serviceProvider.GetService(typeof(IIdentifierCreationService)) as IdentifierCreationService;
                    if (identifierCreationService != null) 
                        provider = identifierCreationService.Provider; 
                }
            } 

            if (provider != null)
                baseIdentifier = provider.CreateValidIdentifier(baseIdentifier);
 
            baseIdentifier = baseIdentifier.Replace('.', '_');
            baseIdentifier = baseIdentifier.Replace('/', '_'); 
            baseIdentifier = baseIdentifier.Replace('(', '_'); 
            baseIdentifier = baseIdentifier.Replace(')', '_');
            baseIdentifier = baseIdentifier.Replace(" ", ""); 

 			ArrayList identifiers = new ArrayList(existingNames);
			int index = 1;
            string finalIdentifier = string.Format(CultureInfo.InvariantCulture, "{0}{1}", baseIdentifier, index); 
 			identifiers.Sort();
			while (identifiers.BinarySearch(finalIdentifier.ToLowerInvariant(), StringComparer.OrdinalIgnoreCase) >= 0) 
			{ 
                finalIdentifier = string.Format(CultureInfo.InvariantCulture, "{0}{1}", baseIdentifier, index);
                index += 1; 
			}
 			return finalIdentifier;
		}
 
        internal static IDictionary GetDeclarativeRules(Activity activity)
        { 
            IDictionary rules = new Dictionary(); 

            Type ruleConditionType = Type.GetType(DeclarativeRulesRef, false); 
            if (ruleConditionType != null)
            {
                PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(activity);
                foreach (PropertyDescriptor property in properties) 
                {
                    object value = property.GetValue(activity); 
                    if (value != null && ruleConditionType.IsAssignableFrom(value.GetType())) 
                    {
                        PropertyDescriptor namePropertyDescriptor = TypeDescriptor.GetConverter(value).GetProperties(new TypeDescriptorContext(activity.Site, null, value), value)["ConditionName"]; 
                        PropertyDescriptor expressionPropertyDescriptor = TypeDescriptor.GetConverter(value).GetProperties(new TypeDescriptorContext(activity.Site, null, value), value)["Expression"];
                        if (namePropertyDescriptor != null && expressionPropertyDescriptor != null)
                        {
                            string ruleName = namePropertyDescriptor.GetValue(value) as String; 
                            object expression = expressionPropertyDescriptor.GetValue(value);
                            if (!string.IsNullOrEmpty(ruleName) && !rules.ContainsKey(ruleName)) 
                            { 
                                string rulesText = (expression != null) ? expressionPropertyDescriptor.Converter.ConvertTo(new TypeDescriptorContext(activity.Site, null, value), System.Threading.Thread.CurrentThread.CurrentUICulture, expression, typeof(string)) as string : null;
                                if (rulesText == null) 
                                    rulesText = string.Empty;

                                rules.Add(ruleName, rulesText);
                            } 
                        }
                    } 
                } 
            }
 
            return rules;
        }

        internal static void RefreshDesignerActions(IServiceProvider serviceProvider) 
        {
            if (serviceProvider != null) 
            { 
                IDesignerHost designerHost = serviceProvider.GetService(typeof(IDesignerHost)) as IDesignerHost;
                if (designerHost != null) 
                {
                    foreach (object component in designerHost.Container.Components)
                    {
                        Activity activity = component as Activity; 
                        if (activity != null)
                        { 
                            ActivityDesigner designer = ActivityDesigner.GetDesigner(activity); 
                            if (designer != null)
                                designer.RefreshDesignerActions(); 
                        }
                    }
                }
            } 
        }
 
        //if a components is a connector, see if it can be removed 
        internal static bool AreComponentsRemovable(ICollection components)
        { 
            if (components == null)
                throw new ArgumentNullException("components");

            foreach (object obj in components) 
            {
                Activity activity = obj as Activity; 
                ConnectorHitTestInfo connector = obj as ConnectorHitTestInfo; 

                //only activities and free form designer connectors are allowed to be deleted 
                if (activity == null && connector == null)
                    return false;

                if (activity != null) 
                {
                    ActivityDesigner designer = ActivityDesigner.GetDesigner(activity); 
                    if (designer != null && designer.IsLocked) 
                        return false;
                } 

                if (connector != null && !(connector.AssociatedDesigner is FreeformActivityDesigner))
                    return false;
            } 

            return true; 
        } 
    }
 
    #region Class DesignerUserDataKeys
    internal static class DesignerUserDataKeys
    {
        internal static readonly Guid DesignerAction = new Guid("3BD4A275-FCCD-49f0-B617-765CE63B4340"); 
        internal static readonly Guid DesignerVerb = new Guid("07E3C73A-5908-4ed1-8578-D1423B7481A2");
        internal static readonly Guid Image = new Guid("B4C2B905-A6D3-4cd6-A91A-5005A02B9676"); 
        internal static readonly Guid ViewActivity = new Guid("06B3FD23-2309-40a9-917E-831B9E160DB0"); 
        internal static readonly Guid PreviewActivity = new Guid("109316ED-A8A5-489f-ABD3-460E5C4C0529");
        internal static readonly Guid DesignerView = new Guid("94B8FC95-2D8A-4e27-93D5-73FA4BEBC315"); 
        internal static readonly Guid TemplateActivityIndex = new Guid("8EA852B4-48FC-45d3-91BE-CA4CF23E9114");
        internal static readonly Guid MoveBranchKey = new Guid("D43D31AA-3C43-4a65-8071-51288B491FBA");
        internal static readonly Guid Designer = new Guid("CF82A1DD-FD3E-4feb-8AED-EE1CAED551D7");
        internal static readonly Guid Activity = new Guid("10BDBBD7-8C63-46e8-B3B8-5006E70820B8"); 
        internal static readonly Guid ZOrderKey = new Guid("8F424588-5227-4273-A594-713454275670");
    } 
    #endregion 

    #region Class DesignerGeometry 
 	internal static class DesignerGeometryHelper
 	{
		#region Helper Methods
        internal static DesignerEdges ClosestEdgeToPoint(Point point, Rectangle rect, DesignerEdges edgesToConsider) 
 		{
            List distances = new List(); 
            List edges = new List(); 

            if ((edgesToConsider & DesignerEdges.Left) > 0) 
            {
                distances.Add(DistanceFromPointToLineSegment(point, new Point[] { new Point(rect.Left, rect.Top), new Point(rect.Left, rect.Bottom) }));
                edges.Add(DesignerEdges.Left);
            } 

            if ((edgesToConsider & DesignerEdges.Top) > 0) 
            { 
                distances.Add(DistanceFromPointToLineSegment(point, new Point[] { new Point(rect.Left, rect.Top), new Point(rect.Right, rect.Top) }));
                edges.Add(DesignerEdges.Top); 
            }

            if ((edgesToConsider & DesignerEdges.Right) > 0)
            { 
                distances.Add(DistanceFromPointToLineSegment(point, new Point[] { new Point(rect.Right, rect.Top), new Point(rect.Right, rect.Bottom) }));
                edges.Add(DesignerEdges.Right); 
            } 

            if ((edgesToConsider & DesignerEdges.Bottom) > 0) 
            {
                distances.Add(DistanceFromPointToLineSegment(point, new Point[] { new Point(rect.Left, rect.Bottom), new Point(rect.Right, rect.Bottom) }));
                edges.Add(DesignerEdges.Bottom);
            } 

            if (distances.Count > 0) 
            { 
                double minDistance = distances[0];
                for (int i = 1; i < distances.Count; i++) 
                    minDistance = Math.Min(minDistance, distances[i]);
                return edges[distances.IndexOf(minDistance)];
            }
            else 
            {
                return DesignerEdges.None; 
            } 
		}
 
		//Find rectangle enclosing line segments
		internal static Rectangle RectangleFromLineSegments(Point[] segments)
 		{
			Debug.Assert(segments.Length > 0); 
 			if (segments.Length == 0)
 				return Rectangle.Empty; 
 
			Point leftTop = segments[0];
 			Point rightBottom = segments[0]; 

			foreach (Point point in segments)
			{
				leftTop.X = Math.Min(leftTop.X, point.X); 
 				leftTop.Y = Math.Min(leftTop.Y, point.Y);
				rightBottom.X = Math.Max(rightBottom.X, point.X); 
 				rightBottom.Y = Math.Max(rightBottom.Y, point.Y); 
 			}
 
			Rectangle enclosingRect = new Rectangle(leftTop, new Size(rightBottom.X - leftTop.X, rightBottom.Y - leftTop.Y));
 			enclosingRect.Inflate(4, 4);
			return enclosingRect;
		} 

		//Is point on line segment 
 		internal static bool PointOnLineSegment(Point point, Point[] line, Size hitAreaSize) 
		{
 			Rectangle rect = RectangleFromLineSegments(line); 

 			rect.Inflate(hitAreaSize);
			if (rect.Contains(point))
 			{ 
				double distance = DistanceFromPointToLineSegment(point, line);
				if (distance < hitAreaSize.Width && distance < hitAreaSize.Height) 
					return true; 
 			}
 
			return false;
 		}

 		//Shortest distance between point and rectangle 
		internal static double DistanceFromPointToRectangle(Point point, Rectangle rect)
 		{ 
			List distances = new List(); 
			distances.Add(DistanceBetweenPoints(point, new Point(rect.Left, rect.Top)));
			distances.Add(DistanceBetweenPoints(point, new Point(rect.Left + rect.Width / 2, rect.Top))); 
 			distances.Add(DistanceBetweenPoints(point, new Point(rect.Right, rect.Top)));
			distances.Add(DistanceBetweenPoints(point, new Point(rect.Right, rect.Top + rect.Height / 2)));
 			distances.Add(DistanceBetweenPoints(point, new Point(rect.Right, rect.Bottom)));
 			distances.Add(DistanceBetweenPoints(point, new Point(rect.Right + rect.Width / 2, rect.Bottom))); 
			distances.Add(DistanceBetweenPoints(point, new Point(rect.Left, rect.Bottom)));
 			distances.Add(DistanceBetweenPoints(point, new Point(rect.Left, rect.Bottom - rect.Height / 2))); 
 
			double minDistance = distances[0];
			for (int i = 1; i < distances.Count; i++) 
				minDistance = Math.Min(minDistance, distances[i]);

 			return minDistance;
		} 

 		//Distance perpendicular from point to line segment 
 		internal static double DistanceFromPointToLineSegment(Point point, Point[] line) 
		{
 			int area = Math.Abs((((point.Y - line[0].Y) * (line[1].X - line[0].X)) - ((point.X - line[0].X) * (line[1].Y - line[0].Y)))); 
			return Math.Sqrt(Math.Pow(area, 2) / (Math.Pow((line[1].X - line[0].X), 2) + Math.Pow((line[1].Y - line[0].Y), 2)));
		}

		//Slope of horizontal line is 0 
 		//Slope of verical line will be infinite and we will represent it as -1
		//Slope of forward \ line will be		(Start at uppper point) 
 		//Slope of backward \ line will be		(Start in lower point) 
 		//Slope of forward / line will be		(Start at uppper point)
		//Slope of forward / line will be		(Start at lower point) 
 		//m = y2-y1 / x2 - x1
		//Line slope is +ve in 1st and 3rd quad and -ve in 2nd and 4th quad
		internal static float SlopeOfLineSegment(Point start, Point end)
		{ 
 			//If line is vertical then the slope is infinite
			if (start.X == end.X) 
 				return float.MaxValue; 

 			//If the line is horizontal then slope is 0 
			if (start.Y == end.Y)
 				return 0;

			return ((float)(end.Y - start.Y)) / (end.X - start.X); 
		}
 
		//Following function is used in two cases 
 		//1. The distance from a line to apoint not on the line is the length of the segment
		//perpendicular to the line from the point 
 		//
 		//2. The distance between two parallel lines is the distance between one of the lines
		//and any point on the other line.
 		//Midpoint of line mid = X1 + X2 / 2, Y1 + Y2 /2 
		//Distance between points d = sqrt(sqr(x2-x1) + sqr(y2-y1))
		internal static double DistanceBetweenPoints(Point point1, Point point2) 
		{ 
 			double d = Math.Sqrt(Math.Pow(point2.X - point1.X, 2) + Math.Pow(point2.Y - point1.Y, 2));
			return d; 
 		}

 		//This function calculates the total length of line segments by adding individual lengths
		internal static double DistanceOfLineSegments(Point[] segments) 
 		{
			double distance = 0; 
			for (int i = 1; i < segments.Length; i++) 
				distance += DistanceBetweenPoints(segments[i - 1], segments[i]);
 			return distance; 
		}

        //Midpoint of line mid = X1 + X2 / 2, Y1 + Y2 /2
        internal static Point MidPointOfLineSegment(Point point1, Point point2) 
        {
            return new Point((point1.X + point2.X) / 2, (point1.Y + point2.Y) / 2); 
        } 
        #endregion
 	} 
 	#endregion
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK