墨迹命中测试示例

此示例演示了在给定屏幕位置的情况下查找墨迹的两种方法。

此示例使用以下功能:

  • 使用墨迹收集器
  • 执行命中测试
  • 查找最近的点

访问墨迹 API

首先,参考位于 Windows Vista 或 Windows XP 平板电脑版软件开发工具包 (SDK) 中的 Tablet 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 命令更新应用程序模式和菜单状态,启用墨迹收集器,并使窗体上以前绘制的区域失效。

“命中测试”和“最接近点”命令都会更改光标、更新应用程序模式和菜单状态、禁用墨迹收集器以及使窗体上以前绘制的区域失效。

清除! 命令在将 InkCollector 对象的 Ink 属性替换为新的 Ink 对象时禁用 InkCollector,生成 Ink 命令事件,并强制刷新控件。

处理鼠标事件

MouseMove 事件处理程序检查应用程序模式:

  • 在墨迹模式下,它不执行任何工作,允许墨迹收集器正常收集墨迹。
  • 在 HitTest 模式下,它将事件参数发送到应用程序的 handleHitTest 方法。
  • 在 NearestPoint 模式下,它将事件参数发送到应用程序的 handleNearestPoint 方法。

执行命中测试

应用程序的 handleHitTest 方法创建两个点,即光标位置和距离光标的一个点 HitSize 像素,然后将这两个点从像素转换为墨迹空间坐标。

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 方法创建两个与光标位置相等的点,其中一个点 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 对象。