スタイラスからの入力のインターセプト

System.Windows.Input.StylusPlugIns アーキテクチャは、Stylus 入力を低レベルで制御し、デジタル インク Stroke オブジェクトを作成するためのメカニズムを提供します。 StylusPlugIn クラスは、カスタム動作を実装し、最適なパフォーマンスを得るためにスタイラス デバイスから送信されるデータストリームに適用するためのメカニズムを提供します。

このトピックには、次のサブセクションが含まれています。

アーキテクチャ

は、ペン入力へのアクセスと操作に関する で説明されている、StylusInput API の進化です。

UIElement には、StylusPlugIns という StylusPlugInCollectionのプロパティがあります。 要素の StylusPlugIn プロパティに StylusPlugIns を追加することで、データが生成される際に StylusPoint を操作できます。 StylusPoint データは、X および Y ポイント データを含む、システム デジタイザーでサポートされているすべてのプロパティと、PressureFactor データで構成されます。

StylusPlugIn オブジェクトは、Stylus プロパティに StylusPlugIn を追加すると、StylusPlugIns デバイスからのデータ ストリームに直接挿入されます。 StylusPlugIns コレクションにプラグインを追加する順序によって、StylusPoint データを受け取る順序が決まります。 たとえば、入力を特定のリージョンに制限するフィルター プラグインを追加した後、ジェスチャの書き込みを認識するプラグインを追加すると、ジェスチャを認識するプラグインは、フィルター処理された StylusPoint データを受け取ります。

スタイラス プラグインの実装

プラグインを実装するには、StylusPlugInからクラスを派生させます。 このクラスは、Stylusから入ってくるデータのストリームに適用されます。 このクラスでは、StylusPoint データの値を変更できます。

注意事項

StylusPlugIn で例外がスローされた場合、またはそれが例外の原因になった場合、アプリケーションは終了します。 StylusPlugIn を使用するコントロールを十分にテストし、StylusPlugIn が例外をスローしないことが確実な場合にのみコントロールを使用する必要があります。

次の例では、X デバイスから取得される Y データの StylusPointStylus の値を変更してスタイラス入力を制限するプラグインを示します。

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 コレクションのメンバーになっているためです。 StylusPlugIn コレクションに追加したカスタム StylusPlugIns は、StylusPoint がデータを受信した後に DynamicRenderer データを受け取ります。 その結果、ユーザーがペンを持ち上げてストロークを終了するまで、StylusPoint データはフィルター処理されません。 ユーザーが描画するときにインクをフィルター処理するには、FilterPluginの前に DynamicRenderer を挿入する必要があります。

次の 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 データへのアクセスレベルが低いため、アプリケーションに最適なパフォーマンスでインクの収集とレンダリングを実装できます。

こちらも参照ください