Within Mi-Forms, it is possible to copy user-added ink strokes from one control to another. There are many reasons this may need to be done. A common example is copying a signature from a freeform field on a form input page into a freeform field on a page that is used to create a PDF output page.
There is an example form provided with the Mi-Forms Designer named "Advanced Ink Copy Example". This is a great place to look to see how to copy ink from one control to another and to see how to appropriately handle the scaling of the ink between controls so that it appears proportional in situations where the source and target fields are different sizes.
However, when you're working with this example, you may notice that if you add ink strokes in the source freeform field, and then delete them, they are still included in the ink that is copied to the various target freeform fields. This is because all ink strokes are retained for each field for auditing purposes; even after they have been "deleted" by a user. Luckily, it turns out that there is an easy way to determine which ink strokes have been deleted and should not be included in your copy process.
The code snippet below shows the addition of a line to delete existing ink strokes from the destination control. And a new If condition has been added to check to see whether a stroke in the source control has been marked as deleted. If it has, then it is not copied to the destination control:
' This subroutine copies ink from one control to another. If the scaleInk parameter is set to true ' then the ink will be scaled to fit the destination control. If not, then the ink will be copied ' at its original scale, which could mean that ink will overlap outside the destination control. Private Sub CopyInk(ByVal sourceCtl As FormControl, ByVal destCtl As FormControl, ByVal scaleInk As Boolean) Dim tx1, ty1, tx2, ty2 As Single Dim sx, sy As Single ' If the ink is to be scaled, we find the X & Y scaling factors here, otherwise we ' just set them to 1 If (scaleInk) Then sx = destCtl.Size.Width / sourceCtl.Size.Width sy = destCtl.Size.Height / sourceCtl.Size.Height Else sx = 1 sy = 1 End If ' This gets the origin X/Y coordinates of the source and destination controls tx1 = sourceCtl.Position.X ty1 = sourceCtl.Position.Y tx2 = destCtl.Position.X ty2 = destCtl.Position.Y ' Clear any previous ink strokes on the destination control. destCtl.ClearStrokes() ' We iterate through every stroke in every InkData object in the source control ' and create a new stroke that will be added to the component. For Each xid As InkData In sourceCtl.InkData For Each xstroke As Stroke In xid.Strokes ' This condition will check to see if the current stroke in the collection ' has already been marked as deleted. ' If it has, then it will not be copied to the destination control. If Not xstroke.Deleted Then Dim xstrokenew As New Stroke For Each xpt As Point In xstroke.Points Dim xptnew As New Point xptnew.X = (xpt.X - tx1) * sx + tx2 xptnew.Y = (xpt.Y - ty1) * sy + ty2 xstrokenew.Points.Add(xptnew) Next ' Note that after we create the new stroke, we're adding it to the component ' instead of directly to the control. Either works, but in this method we're allowing ' the component to handle all events, etc. that would happen if the ink had been ' written on the form directly instead of copied. _component.AddStroke(xstrokenew) End If Next Next End Sub
With just a few simple lines of script as shown above, you can now ensure that only the "current" ink strokes are copied from one control to another.