// ******************************************************************** // Methods // ******************************************************************** #region Methods /// <summary> /// Creates a WPF cursor from a win32 bitmap /// </summary> /// <param name="cursorBitmap"></param> /// <returns></returns> public static SysSystem.Windows.Input.Cursor CreateCursor(SysSystem.Drawing.Bitmap cursorBitmap) { WPFCursorFromBitmap csh = new WPFCursorFromBitmap(cursorBitmap); return(SysSystem.Windows.Interop.CursorInteropHelper.Create(csh)); }
/// <summary> /// Changes the cursor for this control to show the coordinates /// </summary> /// <param name="uiElement"></param> private void SetCoordinatesOnCursor(FrameworkElement uiElement) { Point coordinate = locked ? lockPoint : lastCoordinate; Cursor newCursor = null; SysSystem.Drawing.Font cursorFont = new SysSystem.Drawing.Font("Arial", 8f); try { // Lets get the string to be printed string coordinateText = coordinate.X.ToString(xFormat) + "," + coordinate.Y.ToString(yFormat); // Calculate the rectangle required to draw the string SysSystem.Drawing.SizeF textSize = GetTextSize(coordinateText, cursorFont); // ok, so here's the minimum 1/4 size of the bitmap we need, as the // Hotspot for the cursor will be in the centre of the bitmap. int minWidth = 8 + (int)SysSystem.Math.Ceiling(textSize.Width); int minHeight = 8 + (int)SysSystem.Math.Ceiling(textSize.Height); // If the bitmap needs to be resized, then resize it, else just clear it if (cursorBitmap.Width < minWidth * 2 || cursorBitmap.Height < minHeight * 2) { SysSystem.Drawing.Bitmap oldBitmap = cursorBitmap; cursorBitmap = new SysSystem.Drawing.Bitmap(SysSystem.Math.Max(cursorBitmap.Width, minWidth * 2), SysSystem.Math.Max(cursorBitmap.Height, minHeight * 2)); oldBitmap.Dispose(); } // Get the centre of the bitmap which will be the Hotspot SysSystem.Drawing.Point centre = new SysSystem.Drawing.Point(cursorBitmap.Width / 2, cursorBitmap.Height / 2); /// Calculate the text rectangle SysSystem.Drawing.Rectangle textRectangle = new SysSystem.Drawing.Rectangle(centre.X + 8, centre.Y + 8, minWidth - 8, minHeight - 8); int diff = (int)cursorPosition.X + textRectangle.Right / 2 - 3 - (int)uiElement.ActualWidth; if (diff > 0) { textRectangle.Location = new SysSystem.Drawing.Point(textRectangle.Left - diff, textRectangle.Top); } // Draw the target symbol, and the coordinate text on the bitmap using (SysSystem.Drawing.Graphics g = SysSystem.Drawing.Graphics.FromImage(cursorBitmap)) { g.SmoothingMode = SysSystem.Drawing.Drawing2D.SmoothingMode.AntiAlias; // This line causes a crash on laptops when you render a string // g.CompositingMode = CompositingMode.SourceCopy; g.Clear(SysSystem.Drawing.Color.Transparent); float targetX = centre.X; float targetY = centre.Y; float radius = 30; if (!locked) { SysSystem.Drawing.Pen blackPen = new SysSystem.Drawing.Pen(SysSystem.Drawing.Color.FromArgb(255, 0, 0, 0), 1.4f); g.DrawEllipse(blackPen, targetX - radius * .5f, targetY - radius * .5f, radius, radius); g.DrawLine(blackPen, targetX - radius * .8f, targetY, targetX - 2f, targetY); g.DrawLine(blackPen, targetX + 2f, targetY, targetX + radius * .8f, targetY); g.DrawLine(blackPen, targetX, targetY - radius * .8f, targetX, targetY - 2f); g.DrawLine(blackPen, targetX, targetY + 2f, targetX, targetY + radius * .8f); } else { SysSystem.Drawing.Pen blackPen = new SysSystem.Drawing.Pen(SysSystem.Drawing.Color.FromArgb(255, 0, 0, 0), 3f); SysSystem.Drawing.Pen yellowPen = new SysSystem.Drawing.Pen(SysSystem.Drawing.Color.FromArgb(255, 255, 255, 0), 2f); g.DrawEllipse(blackPen, targetX - radius * .5f, targetY - radius * .5f, radius, radius); g.DrawEllipse(yellowPen, targetX - radius * .5f, targetY - radius * .5f, radius, radius); } if (!locked) { g.FillRectangle(new SysSystem.Drawing.SolidBrush(SysSystem.Drawing.Color.FromArgb(127, 255, 255, 255)), textRectangle); } else { g.FillRectangle(new SysSystem.Drawing.SolidBrush(SysSystem.Drawing.Color.FromArgb(170, 255, 255, 0)), textRectangle); } // Setup the text format for drawing the subnotes using (SysSystem.Drawing.StringFormat stringFormat = new SysSystem.Drawing.StringFormat()) { stringFormat.Trimming = SysSystem.Drawing.StringTrimming.None; stringFormat.FormatFlags = SysSystem.Drawing.StringFormatFlags.NoClip | SysSystem.Drawing.StringFormatFlags.NoWrap; stringFormat.Alignment = SysSystem.Drawing.StringAlignment.Near; // Draw the string left aligned g.DrawString( coordinateText, cursorFont, new SysSystem.Drawing.SolidBrush(SysSystem.Drawing.Color.Black), textRectangle, stringFormat); } } // Now copy the bitmap to the cursor newCursor = WPFCursorFromBitmap.CreateCursor(cursorBitmap); } catch (SysSystem.Exception) { } finally { // After the new cursor has been set, the unmanaged resources can be // cleaned up that were being used by the old cursor if (newCursor != null) { uiElement.Cursor = newCursor; } if (lastCursor != null) { lastCursor.Dispose(); } lastCursor = newCursor; // Save the new values for cleaning up on the next pass } }