Compartir a través de


Interceptar entradas del lápiz óptico

La arquitectura del espacio de nombres System.Windows.Input.StylusPlugIns proporciona un mecanismo para implementar un control de nivel inferior sobre las entradas correspondientes a la clase Stylus y la creación de objetos Stroke de entrada de lápiz digital. La clase StylusPlugIn proporciona un mecanismo para implementar un comportamiento personalizado y aplicarlo a la secuencia de datos procedente del dispositivo de lápiz óptico, a fin de lograr un rendimiento óptimo.

Este tema contiene las siguientes subsecciones:

  • Arquitectura

  • Implementar complementos de lápiz óptico

  • Agregar un complemento a una clase InkCanvas

  • Conclusión

Arquitectura

StylusPlugIn es la evolución de las interfaces de programación de aplicaciones (API) del espacio de nombres StylusInput, que se describen en Accessing and Manipulating Pen Input, de Microsoft Windows XP Tablet PC Edition Software Development Kit 1.7 (todos en inglés).

Cada UIElement tiene una propiedad StylusPlugIns que es una clase StylusPlugInCollection. Puede agregar un objeto StylusPlugIn a la propiedad StylusPlugIns de un elemento para manipular los datos de StylusPoint a medida que generan. Los datos de StylusPoint están compuestos de todas las propiedades admitidas por el digitalizador del sistema, incluidos los datos de los puntos X e Y, así como los datos de PressureFactor.

Los objetos StylusPlugIn se insertan directamente en la secuencia de datos procedente del dispositivo Stylus cuando se agrega StylusPlugIn a la propiedad StylusPlugIns. El orden en que se agregan los complementos a la propiedad StylusPlugIns rige el orden en el que éstos reciben los datos de StylusPoint. Por ejemplo, si agrega un complemento de filtro que restringe la entrada a una región determinada, y, a continuación, agrega un complemento que reconoce los movimientos a medida que se escribe, el complemento que reconoce los movimientos recibe datos filtrados de StylusPoint.

Implementar complementos de lápiz óptico

Para implementar un complemento, derive una clase de StylusPlugIn. Esta clase se aplica a la secuencia de datos a medida que se recibe de Stylus. En esta clase, puede modificar los valores de los datos de StylusPoint.

Nota de precauciónPrecaución

Si StylusPlugIn inicia o produce una excepción, la aplicación se cierra.Debe comprobar exhaustivamente los controles que usan StylusPlugIn y sólo debe usar un control si está seguro de que StylusPlugIn no producirá una excepción.

En el ejemplo siguiente se muestra un complemento que restringe las entradas de lápiz óptico modificando los valores de X e Y en los datos de StylusPoint a medida que entran a través del dispositivo Stylus.

Imports System
Imports System.Windows.Media
Imports System.Windows
Imports System.Windows.Input.StylusPlugIns
Imports System.Windows.Input
Imports System.Windows.Ink


...


' A StylusPlugin that restricts the input area.
Class FilterPlugin
    Inherits StylusPlugIn

    Protected Overrides Sub OnStylusDown(ByVal rawStylusInput As RawStylusInput)
        ' Call the base class before modifying the data.
        MyBase.OnStylusDown(rawStylusInput)

        ' Restrict the stylus input.
        Filter(rawStylusInput)

    End Sub 'OnStylusDown


    Protected Overrides Sub OnStylusMove(ByVal rawStylusInput As RawStylusInput)
        ' Call the base class before modifying the data.
        MyBase.OnStylusMove(rawStylusInput)

        ' Restrict the stylus input.
        Filter(rawStylusInput)

    End Sub 'OnStylusMove


    Protected Overrides Sub OnStylusUp(ByVal rawStylusInput As RawStylusInput)
        ' Call the base class before modifying the data.
        MyBase.OnStylusUp(rawStylusInput)

        ' Restrict the stylus input
        Filter(rawStylusInput)

    End Sub 'OnStylusUp


    Private Sub Filter(ByVal rawStylusInput As RawStylusInput)
        ' Get the StylusPoints that have come in.
        Dim stylusPoints As StylusPointCollection = rawStylusInput.GetStylusPoints()

        ' Modify the (X,Y) data to move the points 
        ' inside the acceptable input area, if necessary.
        Dim i As Integer
        For i = 0 To stylusPoints.Count - 1
            Dim sp As StylusPoint = stylusPoints(i)
            If sp.X < 50 Then
                sp.X = 50
            End If
            If sp.X > 250 Then
                sp.X = 250
            End If
            If sp.Y < 50 Then
                sp.Y = 50
            End If
            If sp.Y > 250 Then
                sp.Y = 250
            End If
            stylusPoints(i) = sp
        Next i

        ' Copy the modified StylusPoints back to the RawStylusInput.
        rawStylusInput.SetStylusPoints(stylusPoints)

    End Sub 'Filter
End Class 'FilterPlugin
using System;
using System.Windows.Media;
using System.Windows;
using System.Windows.Input.StylusPlugIns;
using System.Windows.Input;
using System.Windows.Ink;


...


// A StylusPlugin that restricts the input area.
class FilterPlugin : StylusPlugIn
{
    protected override void OnStylusDown(RawStylusInput rawStylusInput)
    {
        // Call the base class before modifying the data.
        base.OnStylusDown(rawStylusInput);

        // Restrict the stylus input.
        Filter(rawStylusInput);
    }

    protected override void OnStylusMove(RawStylusInput rawStylusInput)
    {
        // Call the base class before modifying the data.
        base.OnStylusMove(rawStylusInput);

        // Restrict the stylus input.
        Filter(rawStylusInput);
    }

    protected override void OnStylusUp(RawStylusInput rawStylusInput)
    {
        // Call the base class before modifying the data.
        base.OnStylusUp(rawStylusInput);

        // Restrict the stylus input
        Filter(rawStylusInput);
    }

    private void Filter(RawStylusInput rawStylusInput)
    {
        // Get the StylusPoints that have come in.
        StylusPointCollection stylusPoints = rawStylusInput.GetStylusPoints();

        // Modify the (X,Y) data to move the points 
        // inside the acceptable input area, if necessary.
        for (int i = 0; i < stylusPoints.Count; i++)
        {
            StylusPoint sp = stylusPoints[i];
            if (sp.X < 50) sp.X = 50;
            if (sp.X > 250) sp.X = 250;
            if (sp.Y < 50) sp.Y = 50;
            if (sp.Y > 250) sp.Y = 250;
            stylusPoints[i] = sp;
        }

        // Copy the modified StylusPoints back to the RawStylusInput.
        rawStylusInput.SetStylusPoints(stylusPoints);
    }
}

Agregar un complemento a una clase InkCanvas

La manera más fácil de utilizar un complemento personalizado es implementar una clase derivada de InkCanvas y agregarla a la propiedad StylusPlugIns.

En el ejemplo siguiente se muestra un control InkCanvas personalizado que filtra las entradas de lápiz.

Public Class FilterInkCanvas
    Inherits InkCanvas
    Private filter As New FilterPlugin()


    Public Sub New()
        Me.StylusPlugIns.Add(filter)

    End Sub 'New
End Class 'FilterInkCanvas
public class FilterInkCanvas : InkCanvas
{
    FilterPlugin filter = new FilterPlugin();

    public FilterInkCanvas()
        : base()
    {
        this.StylusPlugIns.Add(filter);
    }
}

Si agrega FilterInkCanvas a la aplicación y la ejecuta, observará que las entradas de lápiz no se restringen a una región concreta hasta que el usuario ha completado un trazo. Esto se debe a que InkCanvas tiene una propiedad DynamicRenderer, que es una clase StylusPlugIn y ya es miembro de la propiedad StylusPlugIns. El complemento StylusPlugIn personalizado que agregó a la colección StylusPlugIns recibe los datos de StylusPoint después de que DynamicRenderer haya recibido los datos. Como resultado, los datos de StylusPoint no se filtran hasta que el usuario levante el lápiz para finalizar un trazo. Para filtrar las entradas de lápiz mientras el usuario las dibuja, debe insertar el filtro FilterPlugin antes que DynamicRenderer.

El código C# siguiente muestra un control InkCanvas personalizado que filtra las entradas de lápiz mientras se dibujan.

Public Class DynamicallyFilteredInkCanvas
    Inherits InkCanvas

    Private filter As New FilterPlugin()

    Public Sub New()
        Dim dynamicRenderIndex As Integer = Me.StylusPlugIns.IndexOf(Me.DynamicRenderer)

        Me.StylusPlugIns.Insert(dynamicRenderIndex, filter)

    End Sub 'New 

End Class 'DynamicallyFilteredInkCanvas
public class DynamicallyFilteredInkCanvas : InkCanvas
{
    FilterPlugin filter = new FilterPlugin();

    public DynamicallyFilteredInkCanvas()
        : base()
    {
        int dynamicRenderIndex = 
            this.StylusPlugIns.IndexOf(this.DynamicRenderer);

        this.StylusPlugIns.Insert(dynamicRenderIndex, filter);

    }

}

Conclusión

Si deriva sus propias clases StylusPlugIn y las inserta en colecciones StylusPlugInCollection, puede mejorar en gran medida el comportamiento de las entradas de lápiz digitales. El acceso a los datos de StylusPoint a medida que se generan, le permite personalizar la entrada de Stylus. Gracias a este acceso de bajo nivel a los datos de StylusPoint, puede implementarse la recopilación y la representación de las entradas de lápiz con un rendimiento óptimo para la aplicación.

Vea también

Otros recursos

Control avanzado de entrada manuscrita

Obtener acceso y manipular entradas manuscritas