/// <summary> /// Release the memory blocks which has been created for mashalling purpose. /// The method is called from AddStrokes. /// </summary> private void ReleaseResourcesinPacketDescription(MS.Win32.Recognizer.PACKET_DESCRIPTION pd, IntPtr packets) { if (pd.pPacketProperties != IntPtr.Zero) { unsafe { MS.Win32.Recognizer.PACKET_PROPERTY *pPacketProperty = (MS.Win32.Recognizer.PACKET_PROPERTY *)(pd.pPacketProperties.ToPointer( )); MS.Win32.Recognizer.PACKET_PROPERTY *pElement = pPacketProperty; for (int i = 0; i < pd.cPacketProperties; i++) { Marshal.DestroyStructure(new IntPtr(pElement), typeof(MS.Win32.Recognizer.PACKET_PROPERTY)); pElement++; } } Marshal.FreeCoTaskMem(pd.pPacketProperties); pd.pPacketProperties = IntPtr.Zero; } if (pd.pguidButtons != IntPtr.Zero) { Marshal.FreeCoTaskMem(pd.pguidButtons); pd.pguidButtons = IntPtr.Zero; } if (packets != IntPtr.Zero) { Marshal.FreeCoTaskMem(packets); packets = IntPtr.Zero; } }
/// <summary> /// Retrieve the packet description, packets data and XFORM which is the information the native recognizer needs. /// The method is called from AddStrokes. /// </summary> private void GetPacketData ( Stroke stroke, out MS.Win32.Recognizer.PACKET_DESCRIPTION packetDescription, out int countOfBytes, out IntPtr packets, out NativeMethods.XFORM xForm ) { int i; countOfBytes = 0; packets = IntPtr.Zero; packetDescription = new MS.Win32.Recognizer.PACKET_DESCRIPTION(); Matrix matrix = Matrix.Identity; xForm = new NativeMethods.XFORM((float)(matrix.M11), (float)(matrix.M12), (float)(matrix.M21), (float)(matrix.M22), (float)(matrix.OffsetX), (float)(matrix.OffsetY)); StylusPointCollection stylusPoints = stroke.StylusPoints; if (stylusPoints.Count == 0) { return; //we'll fail when the calling routine sees that packets is IntPtr.Zer } if (stylusPoints.Description.PropertyCount > StylusPointDescription.RequiredCountOfProperties) { // // reformat to X, Y, P // StylusPointDescription reformatDescription = new StylusPointDescription( new StylusPointPropertyInfo[] { new StylusPointPropertyInfo(StylusPointProperties.X), new StylusPointPropertyInfo(StylusPointProperties.Y), stylusPoints.Description.GetPropertyInfo(StylusPointProperties.NormalPressure) }); stylusPoints = stylusPoints.Reformat(reformatDescription); } // // now make sure we only take a finite amount of data for the stroke // if (stylusPoints.Count > MaxStylusPoints) { stylusPoints = stylusPoints.Clone(MaxStylusPoints); } Guid[] propertyGuids = new Guid[] { StylusPointPropertyIds.X, //required index for SPD StylusPointPropertyIds.Y, //required index for SPD StylusPointPropertyIds.NormalPressure }; //required index for SPD Debug.Assert(stylusPoints != null); Debug.Assert(propertyGuids.Length == StylusPointDescription.RequiredCountOfProperties); // Get the packet description packetDescription.cbPacketSize = (uint)(propertyGuids.Length * Marshal.SizeOf(typeof(Int32))); packetDescription.cPacketProperties = (uint)propertyGuids.Length; // // use X, Y defaults for metrics, sometimes mouse metrics can be bogus // always use NormalPressure metrics, though. // StylusPointPropertyInfo[] infosToUse = new StylusPointPropertyInfo[StylusPointDescription.RequiredCountOfProperties]; infosToUse[StylusPointDescription.RequiredXIndex] = StylusPointPropertyInfoDefaults.X; infosToUse[StylusPointDescription.RequiredYIndex] = StylusPointPropertyInfoDefaults.Y; infosToUse[StylusPointDescription.RequiredPressureIndex] = stylusPoints.Description.GetPropertyInfo(StylusPointProperties.NormalPressure); MS.Win32.Recognizer.PACKET_PROPERTY[] packetProperties = new MS.Win32.Recognizer.PACKET_PROPERTY[packetDescription.cPacketProperties]; StylusPointPropertyInfo propertyInfo; for (i = 0; i < packetDescription.cPacketProperties; i++) { packetProperties[i].guid = propertyGuids[i]; propertyInfo = infosToUse[i]; MS.Win32.Recognizer.PROPERTY_METRICS propertyMetrics = new MS.Win32.Recognizer.PROPERTY_METRICS( ); propertyMetrics.nLogicalMin = propertyInfo.Minimum; propertyMetrics.nLogicalMax = propertyInfo.Maximum; propertyMetrics.Units = (int)(propertyInfo.Unit); propertyMetrics.fResolution = propertyInfo.Resolution; packetProperties[i].PropertyMetrics = propertyMetrics; } unsafe { int allocationSize = (int)(Marshal.SizeOf(typeof(MS.Win32.Recognizer.PACKET_PROPERTY)) * packetDescription.cPacketProperties); packetDescription.pPacketProperties = Marshal.AllocCoTaskMem(allocationSize); MS.Win32.Recognizer.PACKET_PROPERTY *pPacketProperty = (MS.Win32.Recognizer.PACKET_PROPERTY *)(packetDescription.pPacketProperties.ToPointer()); MS.Win32.Recognizer.PACKET_PROPERTY *pElement = pPacketProperty; for (i = 0; i < packetDescription.cPacketProperties; i++) { Marshal.StructureToPtr(packetProperties[i], new IntPtr(pElement), false); pElement++; } } // Get packet data int[] rawPackets = stylusPoints.ToHiMetricArray(); int packetCount = rawPackets.Length; if (packetCount != 0) { countOfBytes = packetCount * Marshal.SizeOf(typeof(Int32)); packets = Marshal.AllocCoTaskMem(countOfBytes); Marshal.Copy(rawPackets, 0, packets, packetCount); } }