/// <summary> /// Converts Stroke PacketData to an Input array /// </summary> /// <param name="Stroke"> /// The Stroke to convert from</param> /// <param name="destinationRenderer"> /// The renderer to use when converting from hi-metric to pixel coordinates</param> /// <param name="horizontalScaleFactor"> /// The horizontal scaling factor</param> /// <param name="verticalScaleFactor"> /// The vertical scaling factor</param> /// <param name="destinationControl"> /// The control that ink data is played back to</param> /// <param name="inkOffset"> /// The offset to the upper left of the ink data</param> internal static INPUT[] StrokeToInputs( Stroke sourceStroke, Renderer destinationRenderer, Graphics g, float horizontalScaleFactor, float verticalScaleFactor, Control destinationControl, Point inkOffset ) { int [] sourceStrokePacketData = sourceStroke.GetPacketData(); INPUT[] mouseEvents = new INPUT[sourceStrokePacketData.Length/sourceStroke.PacketDescription.Length + 1]; UInt32 tickCount = GetTickCount(); GetBoundsCallback b = new GetBoundsCallback( delegate { return Screen.GetBounds(destinationControl).Size; } ); Size screenSize = (Size)destinationControl.Invoke( b ); // Iterate through each packet set and create a corresponding Mouse based Input structure for (int strokePacketIndex = 0, i = 0; strokePacketIndex < sourceStrokePacketData.Length; strokePacketIndex += sourceStroke.PacketDescription.Length, i++) { // Obtain the packet as a Point from the stroke Point packetPoint = new Point(sourceStrokePacketData[strokePacketIndex] - inkOffset.X, sourceStrokePacketData[strokePacketIndex+1] - inkOffset.Y); // Convert the inkspace coordinate of the packet to a display coordinate destinationRenderer.InkSpaceToPixel(g,ref packetPoint); // Scale the location to the current window packetPoint.X = (int) (packetPoint.X * horizontalScaleFactor); packetPoint.Y = (int) (packetPoint.Y * verticalScaleFactor); // Avoid mouse' enabling and moving the border of the panel) if ( 0 == packetPoint.X) { packetPoint.X = 1; } if ( 0 == packetPoint.Y) { packetPoint.Y = 1; } // Convert the window coordinates to screen coordinates if( destinationControl.InvokeRequired ) { PointScreenCallback z = new PointScreenCallback( delegate { return destinationControl.PointToScreen( packetPoint ); } ); packetPoint = (Point)destinationControl.Invoke( z ); } else packetPoint = destinationControl.PointToScreen( packetPoint ); #region Create the Input structure for the Mouse Event mouseEvents[i].type = INPUT_MOUSE; mouseEvents[i].mi.dx = (packetPoint.X * 65535) / screenSize.Width; mouseEvents[i].mi.dy = (packetPoint.Y * 65535) / screenSize.Height; mouseEvents[i].mi.mouseData = 0; if(0 == strokePacketIndex) { // Move to the start of the stroke mouseEvents[i].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; mouseEvents[i].mi.time = tickCount++; mouseEvents[i].mi.dwExtraInfo = (UIntPtr)0; // Start of the 'stroke' mouseEvents[++i].type = INPUT_MOUSE; mouseEvents[i].mi.dx = (packetPoint.X * 65535) / screenSize.Width; mouseEvents[i].mi.dy = (packetPoint.Y * 65535) / screenSize.Height; mouseEvents[i].mi.mouseData = 0; mouseEvents[i].mi.dwFlags = MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_ABSOLUTE; } else if(sourceStrokePacketData.Length - sourceStroke.PacketDescription.Length <= strokePacketIndex) { // End of the 'stroke' mouseEvents[i].mi.dwFlags = MOUSEEVENTF_LEFTUP | MOUSEEVENTF_ABSOLUTE; } else { // Body of the 'stroke' mouseEvents[i].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; } mouseEvents[i].mi.time = tickCount++; mouseEvents[i].mi.dwExtraInfo = (UIntPtr)0; #endregion } return mouseEvents; }
internal static extern uint SendInput( uint inputCount, INPUT[] inputs, int size );