次の方法で共有


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

System.Windows.Input.StylusPlugIns アーキテクチャは、Stylus 入力およびデジタル インクの Stroke オブジェクトの作成に対する低レベルの制御を実装するための機構です。 StylusPlugIn クラスは、カスタム動作を実装し、その動作をスタイラス デバイスから取得されるデータのストリームに適用するための機構で、最高のパフォーマンスを実現するように作られています。

このトピックは、次の内容で構成されています。

  • アーキテクチャ

  • スタイラス プラグインを実装する

  • InkCanvas にプラグインを追加する

  • まとめ

アーキテクチャ

StylusPlugIn は、StylusInput の API を発展させたものです。この API については、「Microsoft Windows XP Tablet PC Edition Software Development Kit 1.7」の「Accessing and Manipulating Pen Input」を参照してください。

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

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

スタイラス プラグインを実装する

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

Caution メモ注意

StylusPlugIn が例外をスローまたは発生させた場合、アプリケーションは終了します。StylusPlugIn を使用するコントロールを十分にテストし、StylusPlugIn が例外をスローしないことが確実な場合だけ、コントロールを使用するようにしてください。

Stylus デバイスから受け取る StylusPoint データの XY の値を変更することでスタイラス入力を制限するプラグインの例を次に示します。

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);
    }
}

InkCanvas にプラグインを追加する

カスタム プラグインを使用するための最も簡単方法は、InkCanvas から派生するクラスを実装し、StylusPlugIns プロパティに追加することです。

インクをフィルター処理するカスタム InkCanvas の例を次に示します。

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);
    }
}

FilterInkCanvas をアプリケーションに追加して実行すると、ユーザーがストロークを完了するまでインクは一定の領域に制限されないことがわかります。 これは、InkCanvas には DynamicRenderer プロパティがあり、このプロパティは StylusPlugIn で、既に StylusPlugIns コレクションのメンバーであるためです。 StylusPlugIns コレクションに追加したカスタム StylusPlugIn は、DynamicRendererStylusPoint データを受信した後に、そのデータを受信します。 その結果、StylusPoint データがフィルター処理されるのは、ユーザーがペンを持ち上げてストロークを完了したときとなります。 ユーザーがインクを描画した時点でインクをフィルター処理するには、FilterPlugin を DynamicRenderer の前に挿入する必要があります。

次の C# コードは、インク描画時にフィルター処理するカスタム InkCanvas を示しています。

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);

    }

}

まとめ

独自の StylusPlugIn クラスを派生させて StylusPlugInCollection コレクションに挿入することで、デジタル インクの動作を大幅に向上させることができます。 StylusPoint データが生成された時点でアクセスできるので、Stylus 入力をカスタマイズできるようになります。 このような、低レベルでの StylusPoint データへのアクセスが可能であることから、アプリケーションでのインク収集およびレンダリングの実装のパフォーマンスが最大になります。

参照

その他の技術情報

高度なインク処理

Accessing and Manipulating Pen Input (ペン入力のアクセスと操作)