/// <summary> /// Plays back ink data to a specified control /// </summary> /// <param name="destinationControl"> /// The control to play the Ink Data to.</param> /// <param name="destinationRenderer"> /// The Ink Renderer used to convert ink data to display coordinates</param> /// <param name="keepDestinationAspectRatio"> /// Specified whether to keep original aspect ratio of ink when scaling</param> /// <param name="playbackRate"> /// The rate at which to play back the Ink Data</param> protected void PlaybackRecordedData( Control destinationControl, bool keepDestinationAspectRatio, PacketPlaybackRate playbackRate, System.Drawing.Drawing2D.Matrix iTrans) { if( null != PlaybackInk ) { System.Drawing.Graphics g = destinationControl.CreateGraphics(); Microsoft.Ink.Renderer destinationRenderer = new Microsoft.Ink.Renderer(); destinationRenderer.SetViewTransform( iTrans ); // Set whether or not to keep ink aspect ratio in the display window bool keepAspectRatio = keepDestinationAspectRatio; // Declare scaling factors float scaleFactorX = 1.0f; float scaleFactorY = 1.0f; // Get the size of the display window System.Drawing.Size displayWindowSize = destinationControl.ClientSize; // Get ink bounding box in ink space; convert the box's size to pixel; System.Drawing.Rectangle inkBoundingBox = PlaybackInk.GetBoundingBox(); // Set the size and offset of the destination input System.Drawing.Point inkBoundingBoxSize = new System.Drawing.Point(inkBoundingBox.Width, inkBoundingBox.Height); // Convert the inkspace coordinate to pixels destinationRenderer.InkSpaceToPixel(g, ref inkBoundingBoxSize); // Get the offset of ink System.Drawing.Point inkOffset = inkBoundingBox.Location; // Determine what the scaling factor of the destination control is so // we know how to correctly resize the ink data getDisplayWindowScalingFactor(new System.Drawing.Size(inkBoundingBoxSize), displayWindowSize, keepAspectRatio, ref scaleFactorX, ref scaleFactorY); // Iterate through all ink strokes and extract the packet data foreach ( Microsoft.Ink.Stroke currentStroke in PlaybackInk.Strokes ) { // Convert the stroke's packet data to INPUT structs INPUT[] inputs = SendInputInterop.StrokeToInputs( currentStroke, destinationRenderer, g, scaleFactorX, scaleFactorY, destinationControl, inkOffset ); if ( null != inputs ) { // Iterate through all the extracted INPUT data in order to send to destination control for ( int i = 0; i < inputs.Length; i++ ) { // Use the Win32 SendInput API to send the ink data point to the control // Note that all playback will use the upper left of the destination control // as the origin SendInputInterop.SendInput( 1, new INPUT[] { inputs[i] }, System.Runtime.InteropServices.Marshal.SizeOf( inputs[i] ) ); // Determine the delay between packets (within a stroke) switch( playbackRate ) { case PacketPlaybackRate.Default: default: System.Threading.Thread.Sleep(5); break; case PacketPlaybackRate.Slow: System.Threading.Thread.Sleep(100); break; case PacketPlaybackRate.Fast: break; } } } // Reset the focus to the destination control in case it has been changed if( destinationControl.InvokeRequired ) { GenericVoidCallback func = new GenericVoidCallback( delegate { destinationControl.Focus(); } ); destinationControl.Invoke( func ); } else destinationControl.Focus(); // Create a delay between each stroke if ( 0 != InterStrokeDelay) { System.Threading.Thread.Sleep((int)(InterStrokeDelay)); } } // dispose the graphics object g.Dispose(); } }
/// <summary> /// Plays back ink data to a specified control /// </summary> /// <param name="destinationControl"> /// The control to play the Ink Data to.</param> /// <param name="destinationRenderer"> /// The Ink Renderer used to convert ink data to display coordinates</param> /// <param name="keepDestinationAspectRatio"> /// Specified whether to keep original aspect ratio of ink when scaling</param> /// <param name="playbackRate"> /// The rate at which to play back the Ink Data</param> protected void PlaybackRecordedData(Control destinationControl, bool keepDestinationAspectRatio, PacketPlaybackRate playbackRate, System.Drawing.Drawing2D.Matrix iTrans) { if (null != PlaybackInk) { System.Drawing.Graphics g = destinationControl.CreateGraphics(); Microsoft.Ink.Renderer destinationRenderer = new Microsoft.Ink.Renderer(); destinationRenderer.SetViewTransform(iTrans); // Set whether or not to keep ink aspect ratio in the display window bool keepAspectRatio = keepDestinationAspectRatio; // Declare scaling factors float scaleFactorX = 1.0f; float scaleFactorY = 1.0f; // Get the size of the display window System.Drawing.Size displayWindowSize = destinationControl.ClientSize; // Get ink bounding box in ink space; convert the box's size to pixel; System.Drawing.Rectangle inkBoundingBox = PlaybackInk.GetBoundingBox(); // Set the size and offset of the destination input System.Drawing.Point inkBoundingBoxSize = new System.Drawing.Point(inkBoundingBox.Width, inkBoundingBox.Height); // Convert the inkspace coordinate to pixels destinationRenderer.InkSpaceToPixel(g, ref inkBoundingBoxSize); // Get the offset of ink System.Drawing.Point inkOffset = inkBoundingBox.Location; // Determine what the scaling factor of the destination control is so // we know how to correctly resize the ink data getDisplayWindowScalingFactor(new System.Drawing.Size(inkBoundingBoxSize), displayWindowSize, keepAspectRatio, ref scaleFactorX, ref scaleFactorY); // Iterate through all ink strokes and extract the packet data foreach (Microsoft.Ink.Stroke currentStroke in PlaybackInk.Strokes) { // Convert the stroke's packet data to INPUT structs INPUT[] inputs = SendInputInterop.StrokeToInputs(currentStroke, destinationRenderer, g, scaleFactorX, scaleFactorY, destinationControl, inkOffset); if (null != inputs) { // Iterate through all the extracted INPUT data in order to send to destination control for (int i = 0; i < inputs.Length; i++) { // Use the Win32 SendInput API to send the ink data point to the control // Note that all playback will use the upper left of the destination control // as the origin SendInputInterop.SendInput(1, new INPUT[] { inputs[i] }, System.Runtime.InteropServices.Marshal.SizeOf(inputs[i])); // Determine the delay between packets (within a stroke) switch (playbackRate) { case PacketPlaybackRate.Default: default: System.Threading.Thread.Sleep(5); break; case PacketPlaybackRate.Slow: System.Threading.Thread.Sleep(100); break; case PacketPlaybackRate.Fast: break; } } } // Reset the focus to the destination control in case it has been changed if (destinationControl.InvokeRequired) { GenericVoidCallback func = new GenericVoidCallback(delegate { destinationControl.Focus(); }); destinationControl.Invoke(func); } else { destinationControl.Focus(); } // Create a delay between each stroke if (0 != InterStrokeDelay) { System.Threading.Thread.Sleep((int)(InterStrokeDelay)); } } // dispose the graphics object g.Dispose(); } }