次の方法で共有


インク スレッド モデル

タブレット PC のインクの利点の 1 つが、通常のペンを使って紙に書く感覚に非常に似ていることです。 これを実現するために、タブレット ペンでは、マウスよりもはるかに高速に入力データが収集され、ユーザーが書くときに、インクがレンダリングされます。 アプリケーションのユーザー インターフェイス (UI) スレッドは、ペン データを収集してインクをレンダリングするのに十分ではありません。ブロックされる可能性があるためです。 これを解決するには、ユーザーがインクを書き込むときに、WPF アプリケーションで、2 つの追加のスレッドを使用します。

次の一覧は、デジタル インクの収集とレンダリングに参加するスレッドを示しています。

  • ペン スレッド - スタイラスからの入力を受け取るスレッド (実際には、これはスレッド プールですが、このトピックではペン スレッドと呼びます)。

  • アプリケーション ユーザー インターフェイス スレッド - アプリケーションのユーザー インターフェイスを制御するスレッド。

  • 動的レンダリング スレッド - ユーザーがストロークを描画している間、インクをレンダリングするスレッド。 動的レンダリング スレッドは、Window Presentation Foundation スレッド モデルに説明されているように、アプリケーションの他の UI 要素をレンダリングするスレッドとは別です。

アプリケーションで使用されるのが、InkCanvas でも、インク入力コントロール作成時のものに似たカスタム コントロールでも、インク モデルは同じです。 このトピックでは、スレッドについて InkCanvas の観点から説明しますが、カスタム コントロールを作成する場合も同じ概念が適用されます。

スレッドの概要

次の図は、ユーザーがストロークを描画するときのスレッド モデルを示しています。

Threading model while drawing a stroke.

  1. ユーザーがストロークを描画している間発生するアクション

    1. ユーザーがストロークを描画すると、スタイラス ポイントがペン スレッドに送られます。 ペン スレッドで、DynamicRenderer などのスタイラス プラグインにより、スタイラス ポイントが受け入れられ、InkCanvas によって受け取られる前に変更することができます。

    2. 動的レンダリング スレッドで、DynamicRenderer により、スタイラス ポイントがレンダリングされます。 これは、前のステップと同時に発生します。

    3. UI スレッドで、InkCanvas により、スタイラス ポイントが受け取られます。

  2. ユーザーがストロークを終了した後に発生するアクション

    1. ユーザーがストロークの描画を終了すると、InkCanvas により Stroke オブジェクトが作成され、InkPresenter に追加されます。これにより、静的にレンダリングされます。

    2. UI スレッドにより、ストロークが静的にレンダリングされたことが DynamicRenderer に警告され、DynamicRenderer で、ストロークの視覚表示が削除されます。

インク コレクションとスタイラス プラグイン

UIElement には StylusPlugInCollection が含まれます。 StylusPlugInCollection 内の StylusPlugIn オブジェクトで、ペン スレッドのスタイラス ポイントを受け取り、変更することができます。 StylusPlugIn オブジェクトにより、StylusPlugInCollection の順序に従ってスタイラス ポイントを受け取られます。

次の図は、UIElementStylusPlugIns コレクションに stylusPlugin1DynamicRendererstylusPlugin2 がこの順序で含まれているという仮定の状況を示しています。

Order of Stylus Plugins affect output.

上の図では、次の動作が行われます。

  1. StylusPlugin1 で、x と y の値が変更されます。

  2. DynamicRenderer で、変更されたスタイラス ポイントが受け取られ、動的レンダリング スレッド上にレンダリングされます。

  3. StylusPlugin2 で、変更されたスタイラス ポイントが受け取られ、x と y の値がさらに変更されます。

  4. アプリケーションで、スタイラス ポイントが収集され、ユーザーがストロークを終了したときに、ストロークが静的にレンダリングされます。

stylusPlugin1 で、スタイラス ポイントが四角形に制限され、stylusPlugin2 で、スタイラス ポイントを右に移動するとします。 前のシナリオでは、DynamicRenderer で、制限付きのスタイラス ポイントを受け取りますが、移動されたスタイラス ポイントは受け取りません。 ユーザーがストロークを描画すると、ストロークは四角形の境界内にレンダリングされますが、ユーザーがペンを持ち上げるまでストロークは移動したようには見えません。

UI スレッドでスタイラス プラグインを使用して操作を実行する

ペン スレッドでは正確なヒットテストを実行できないため、一部の要素で、他の要素向けのスタイラス入力が受け取られることがあります。 操作を実行する前に入力が正しくルーティングされたことを確認する必要がある場合は、OnStylusDownProcessedOnStylusMoveProcessed、または OnStylusUpProcessed メソッドをサブスクライブし、操作を実行します。 これらのメソッドは、正確なヒットテストが実行された後に、アプリケーション スレッドから呼び出されます。 これらのメソッドをサブスクライブするには、ペン スレッドで発生するメソッド内で NotifyWhenProcessed メソッドを呼び出します。

次の図は、StylusPlugIn のスタイラス イベントに関するペン スレッドと UI スレッドの関係を示しています。

Ink Threading Models (UI and Pen)

インクのレンダリング

ユーザーがストロークを描画すると、DynamicRenderer で、インクが別のスレッドにレンダリングされます。これにより、UI スレッドがビジー状態の場合でも、ペンからインクが "流れている" ように見えます。 DynamicRenderer で、スタイラス ポイントが収集されるときに、動的レンダリング スレッドにビジュアル ツリーが構築されます。 ユーザーがストロークを終了すると、DynamicRenderer により、アプリケーションで次のレンダリング パスを実行したときに通知を受け取るように要求されます。 アプリケーションで次のレンダリング パスが完了した後、DynamicRenderer では、ビジュアル ツリーがクリーンアップされます。 このプロセスを説明する図を次に示します。

Ink threading diagram

  1. ユーザーがストロークを開始します。

    1. DynamicRenderer で、ビジュアル ツリーが作成されます。
  2. ユーザーがストロークを描画し続けています。

    1. DynamicRenderer で、ビジュアル ツリーが構築されます。
  3. ユーザーがストロークを終了します。

    1. InkPresenter により、そのビジュアル ツリーにストロークが追加されます。

    2. メディア統合レイヤー (MIL) により、ストロークが静的にレンダリングされます。

    3. DynamicRenderer で、ビジュアルがクリーンアップされます。