스타일러스에서 입력 가로채기

System.Windows.Input.StylusPlugIns 아키텍처는 Stylus 입력에 대한 하위 수준 제어를 구현하고 디지털 잉크 Stroke 개체를 만드는 메커니즘을 제공합니다. StylusPlugIn 클래스는 사용자 지정 동작을 구현하고 최적의 성능을 위해 스타일러스 디바이스를 통해 입력되는 데이터 스트림에 적용하는 메커니즘을 제공합니다.

이 항목에는 다음과 같은 하위 단원이 포함되어 있습니다.

아키텍처

StylusPlugIn펜 입력 액세스 및 조작에 설명된 StylusInput API의 진화입니다.

UIElementStylusPlugIns 속성에는 StylusPlugInCollection. StylusPlugIn을 요소의 StylusPlugIns 속성에 추가하여 생성되는 StylusPoint 데이터를 조작할 수 있습니다. StylusPoint 데이터는 XY 포인트 데이터와 PressureFactor 데이터를 포함하여 시스템 디지타이저에서 지원하는 모든 속성으로 구성됩니다.

StylusPlugIn 개체는 StylusPlugIns 속성에 StylusPlugIn을 추가하면 Stylus 디바이스에서 오는 데이터 스트림에 직접 삽입됩니다. 플러그 인이 StylusPlugIns 컬렉션에 추가되는 순서는 플러그 인이 StylusPoint 데이터를 받는 순서를 나타냅니다. 예를 들어 입력을 특정 지역으로 제한하는 필터 플러그 인을 추가한 다음, 제스처가 쓰여질 때 제스처를 인식하는 플러그 인을 추가하면 제스처를 인식하는 플러그 인은 필터링된 StylusPoint 데이터를 받게 됩니다.

스타일러스 플러그 인 구현

플러그 인을 구현하려면 StylusPlugIn에서 클래스를 파생시킵니다. 이 클래스는 데이터 스트림이 Stylus에서 들어올 때 데이터 스트림에 적용됩니다. 이 클래스에서 StylusPoint 데이터의 값을 수정할 수 있습니다.

주의

StylusPlugIn에서 예외가 발생하거나 예외를 발생시키면 애플리케이션이 닫힙니다. StylusPlugIn을 사용하는 컨트롤을 철저히 테스트하고 StylusPlugIn에서 예외가 발생하지 않을 것이라고 확신하는 경우에만 컨트롤을 사용해야 합니다.

다음 예제에서는 Stylus 디바이스에서 들어오는 StylusPoint 데이터의 XY 값을 수정하여 스타일러스 입력을 제한하는 플러그 인을 보여줍니다.

using System;
using System.Windows.Media;
using System.Windows;
using System.Windows.Input.StylusPlugIns;
using System.Windows.Input;
using System.Windows.Ink;
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 : 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);
    }
}
' 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


    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


    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


    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
End Class

InkCanvas에 플러그 인 추가

사용자 지정 플러그 인을 사용하는 가장 쉬운 방법은 InkCanvas에서 파생된 클래스를 구현하고 이를 StylusPlugIns 속성에 추가하는 것입니다.

다음 예제에서는 잉크를 필터링하는 사용자 지정 InkCanvas를 보여줍니다.

public class FilterInkCanvas : InkCanvas
{
    FilterPlugin filter = new FilterPlugin();

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

애플리케이션에 FilterInkCanvas를 추가하고 실행하면 사용자가 스트로크를 완료할 때까지는 잉크가 지역으로 제한되지 않는 것을 볼 수 있습니다. InkCanvasDynamicRenderer 속성이 있고 이것은 StylusPlugIn이며 이미 StylusPlugIns 컬렉션의 멤버이기 때문입니다. StylusPlugIns 컬렉션에 추가한 사용자 지정 StylusPlugInDynamicRenderer가 데이터를 받은 후 StylusPoint 데이터를 받습니다. 따라서 StylusPoint 데이터는 사용자가 펜을 들어 올려 스트로크를 끝낼 때까지 필터링되지 않습니다. 사용자가 그릴 때 잉크를 필터링하려면 DynamicRenderer 앞에 FilterPlugin을 삽입해야 합니다.

다음 C# 코드는 잉크를 그릴 때 필터링하는 사용자 지정 InkCanvas를 보여줍니다.

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

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

        this.StylusPlugIns.Insert(dynamicRenderIndex, filter);
    }
}

결론

고유한 StylusPlugIn 클래스를 파생시켜서 StylusPlugInCollection 컬렉션에 삽입하면 디지털 잉크의 동작을 크게 향상시킬 수 있습니다. StylusPoint 데이터가 생성될 때 액세스할 수 있으므로 Stylus 입력을 사용자 지정할 수 있습니다. StylusPoint 데이터에 대한 액세스 수준이 낮기 때문에 잉크 컬렉션을 구현하고 애플리케이션에 대한 최적 성능으로 렌더링할 수 있습니다.

참고 항목