次の方法で共有


インク ヒット テスト サンプル

このサンプルでは、画面の場所を指定してインクを検索する 2 つの方法を示します。

このサンプルでは、次の機能を使用します。

  • インク コレクターの使用
  • ヒット テストの実行
  • 最も近いポイントの検索

Ink API へのアクセス

まず、Windows Vista または Windows XP Tablet PC Edition Software Development Kit (SDK) にあるタブレット PC クラスを参照します。

using Microsoft.Ink;

フォームの読み込みイベントとペイント イベントの処理

フォームの Load イベント ハンドラー:

// Create the InkCollector, and turn it on
ic = new InkCollector(Handle);  // attach it to the form's frame window

// default to ink-enabled mode
mode = ApplicationMode.Ink;
ic.CollectionMode = CollectionMode.InkOnly;

// turn the collector on
ic.Enabled = true;ic.AutoRedraw = true;

フォームの Paint イベント ハンドラーは、アプリケーション モードを確認します。

  • HitTest モードでは、カーソルの周りに円が描画されます。 アクティブなペンは、アプリケーションの handleHitTest メソッドで設定されます。
  • NearestPoint モードでは、カーソルとカーソルの最も近いポイントの間に赤い線が描画されます。 最も近い点は、アプリケーションの handleNearestPoint メソッドで計算されます。
if( mode == ApplicationMode.HitTest)
{
    e.Graphics.DrawEllipse(activepen, penPt.X - HitSize/2, penPt.Y - HitSize/2, HitSize, HitSize);
}
else if( mode == ApplicationMode.NearestPoint )
{
    e.Graphics.DrawLine(redPen, penPt, nearestPt);
}

このサンプルには、非常に簡単な再描画アルゴリズムがあります。 AutoRedraw プロパティを TRUE に設定すると、フォームの再描画時にインク コレクター自体が再描画されます。 フォームの再描画を簡略化するために、アプリケーションは、ペイントが追加される領域の境界ボックス invalidateRect メンバー変数を追跡します。これは、フォームが再描画されるたびに無効になります。

メニュー イベントの処理

Exit コマンドは、アプリケーションを終了する前に InkCollector を無効にします。

Ink コマンドは、アプリケーション モードとメニューの状態を更新し、インク コレクターを有効にして、フォームの以前に塗りつぶした領域を無効にします。

[ヒット テスト] コマンドと [最も近いポイント] コマンドの両方でカーソルが変更され、アプリケーション モードとメニューの状態が更新され、インク コレクターが無効になり、フォームの以前に塗られた領域が無効になります。

クリア! command は InkCollector オブジェクトの Ink プロパティ を新しい Ink オブジェクトに置き換えながら InkCollector を無効にし、Ink コマンド イベントを生成し、コントロールの更新を強制します。

マウス イベントの処理

MouseMove イベント ハンドラーは、アプリケーション モードを確認します。

  • インク モードでは何も行わないので、インク コレクターによってインクを通常どおりに収集できます。
  • HitTest モードでは、イベント引数をアプリケーションの handleHitTest メソッドに送信します。
  • NearestPoint モードでは、イベント引数をアプリケーションの handleNearestPoint メソッドに送信します。

ヒット テストの実行

アプリケーションの handleHitTest メソッドは、カーソル位置とカーソルから離れたポイント HitSize ピクセルの 2 つのポイントを作成し、これら 2 つのポイントをピクセルからインク空間座標に変換します。

penPt = new Point(e.X, e.Y);
Point pt2 = new Point(e.X, e.Y);
Point pt3 = new Point(e.X + HitSize/2, e.Y);

using (Graphics g = CreateGraphics())
{
    ic.Renderer.PixelToInkSpace(g, ref pt1);
    ic.Renderer.PixelToInkSpace(g, ref pt2);
}

次に、 InkCollector オブジェクトは Microsoft.Ink.Ink.HitTest() メソッドを使用して、pt3 内にあるストロークを検索します。X - pt2。カーソルの X インク空間ユニット pt2。

Strokes strokes = ic.Ink.HitTest(pt2, (float)(pt3.X - pt2.X));

次に、handleHitTest メソッドは、ストロークが見つかったかどうかに基づいてペンの色を設定し、invalidateRect 領域を無効にし、ヒット テスト円が描画される新しい領域を計算してから、新しい領域を無効にします。

最も近いポイントの検索

アプリケーションの handleNearestPoint メソッドは、カーソルの位置と等しい 2 つのポイントを作成します。これらのポイントの 1 つである pt はインク空間に変換され、 InkCollectorInk オブジェクトの NearestPoint メソッドの呼び出しで使用されます。 NearestPoint メソッドは、ポイントに最も近い Stroke オブジェクトを返し、浮動小数点インデックス出力パラメーターを設定します。

using (Graphics g = CreateGraphics())
{

   // Remember pen location
    Point inkPenPt = new Point(e.X, e.Y);

    // Convert the pen location into a location in ink space
    ic.Renderer.PixelToInkSpace(g, ref inkPenPt);

    // ...

    float fIndex;
    Stroke stroke = ic.Ink.NearestPoint(inkPenPt, out fIndex);

ストロークが存在しない場合、NearestPoint メソッドは NULL を返し、カーソル位置が最も近いポイントとして使用されます。 それ以外の場合は、浮動小数点インデックスに対応するストローク上の位置が計算されます。

次に、最も近いポイント座標がインク空間からピクセルに変換されます。handleNearestPoint メソッドは、invalidateRect 領域を無効にし、最も近いポイントへの線が描画される新しい領域を計算し、新しい領域も無効にします。

フォームを閉じる

フォームの Dispose メソッドは InkCollector オブジェクトを破棄します。