このサンプルでは、画面の場所を指定してインクを検索する 2 つの方法を示します。
このサンプルでは、次の機能を使用します。
- インク コレクターの使用
- ヒット テストの実行
- 最も近いポイントの検索
Ink API へのアクセス
まず、Windows Vista または Windows XP Tablet PC Edition Software Development Kit (SDK) にあるタブレット PC クラスを参照します。
using Microsoft.Ink;
フォームの読み込みイベントとペイント イベントの処理
フォームの Load イベント ハンドラー:
- フォームの InkCollector オブジェクト ic を作成します。
- ジェスチャを無視するように InkCollector オブジェクトの CollectionMode プロパティを設定します。
- InkCollector を有効にします。
- InkCollector オブジェクトの AutoRedraw プロパティを TRUE に設定します。
// 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 はインク空間に変換され、 InkCollector の Ink オブジェクトの 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 オブジェクトを破棄します。