墨迹命中测试示例
此示例演示了在给定屏幕位置的情况下查找墨迹的两种方法。
此示例使用以下功能:
- 使用墨迹收集器
- 执行命中测试
- 查找最近的点
访问墨迹 API
首先,参考位于 Windows Vista 或 Windows XP 平板电脑版软件开发工具包 (SDK) 中的 Tablet 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 命令更新应用程序模式和菜单状态,启用墨迹收集器,并使窗体上以前绘制的区域失效。
“命中测试”和“最接近点”命令都会更改光标、更新应用程序模式和菜单状态、禁用墨迹收集器以及使窗体上以前绘制的区域失效。
清除! 命令在将 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 将转换为墨迹空间,并在调用 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 对象。