RealTimeStylus Ink 集合示例
此应用程序演示使用 RealTimeStylus 类时的墨迹收集和呈现。
InkCollection 项目
此示例由包含一个项目 InkCollection 的单个解决方案组成。 应用程序定义 InkCollection
包含单个类的命名空间,也称为 InkCollection
。 类继承自 Form 类,并实现 IStylusAsyncPlugin 接口。
namespace InkCollection
{
public class InkCollection : Form, IStylusAsyncPlugin
{
//...
InkCollection 类定义一组专用常量,用于指定各种墨迹粗细。 类还声明 RealTimeStylus 类、myRealTimeStylus
DynamicRenderer 类和 Renderer 类myRenderer
myDynamicRenderer
的私有实例。
DynamicRenderer 呈现当前正在收集的笔划。 Renderer 对象 myRenderer
呈现已收集的 Stroke 对象。
private const float ThinInkWidth = 10;
private const float MediumInkWidth = 100;
private const float ThickInkWidth = 200;
private RealTimeStylus myRealTimeStylus;
private DynamicRenderer myDynamicRenderer;
private Renderer myRenderer;
类还声明 一个 Hashtable 对象 , myPackets
该对象用于存储由一个或多个 Cursor 对象收集的数据包数据。
Stylus 对象的 Id 值用作哈希表键,以唯一标识为给定 Cursor 对象收集的数据包数据。
Ink 对象的私有实例,myInk
存储由 收集的 myRealTimeStylus
Stroke 对象。
private Hashtable myPackets;
private Ink myInk;
窗体加载事件
在窗体的 Load 事件处理程序中, myDynamicRenderer
通过使用将控件作为参数的 DynamicRenderer 实例化,并使用 myRenderer
无参数构造函数进行构造。
private void InkCollection_Load(object sender, System.EventArgs e)
{
myDynamicRenderer = new DynamicRenderer(this);
myRenderer = new Renderer();
// ...
请注意呈现器实例化后的注释,因为在 myDynamicRenderer
呈现墨迹时使用 DrawingAttributes 的默认值。 这是标准行为。 但是,如果要为呈现myDynamicRenderer
的墨迹提供与 呈现myRenderer
的墨迹不同的外观,可以更改 上的 myDynamicRenderer
DrawingAttributes 属性。 为此,请在生成并运行应用程序之前取消注释以下行。
// myDynamicRenderer.DrawingAttributes.PenTip = PenTip.Rectangle;
// myDynamicRenderer.DrawingAttributes.Height = (.5F)*MediumInkWidth;
// myDynamicRenderer.DrawingAttributes.Transparency = 128;
接下来,应用程序创建 RealTimeStylus 对象,该对象用于接收触笔通知,并将 DynamicRenderer 对象添加到同步插件通知队列。 具体而言, myRealTimeStylus
将 添加到 myDynamicRenderer
SyncPluginCollection 属性。
myRealTimeStylus = new RealTimeStylus(this, true);
myRealTimeStylus.SyncPluginCollection.Add(myDynamicRenderer);
然后,窗体将添加到异步插件通知队列。 具体而言, InkCollection
添加到 AsyncPluginCollection 属性。 最后, myRealTimeStylus
启用 和 myDynamicRenderer
,并实例化 myPackets 和 myInk。
myRealTimeStylus.AsyncPluginCollection.Add(this);
myRealTimeStylus.Enabled = true;
myDynamicRenderer.Enabled = true;
myPackets = new Hashtable();
myInk = new Ink();
}
除了挂接用于更改墨迹颜色和大小的菜单处理程序外,在实现接口之前还需要一个简短的代码块。 该示例必须处理窗体的 Paint 事件。 在事件处理程序中,应用程序必须刷新 myDynamicRenderer
,因为可能在 Paint 事件发生时收集 Stroke 对象。 在这种情况下,需要重新绘制已收集的 Stroke 对象的部分。 静态 呈现器 用于重新绘制已收集的 Stroke 对象。 这些笔划位于 Ink 对象中,因为它们在绘制时放置在其中,如下一部分所示。
private void InkCollection_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
myDynamicRenderer.Refresh();
myRenderer.Draw(e.Graphics, myInk.Strokes);
}
实现 IStylusAsyncPlugin 接口
示例应用程序定义它有兴趣在 DataInterest 属性的实现中接收的通知类型。 因此,DataInterest 属性定义 RealTimeStylus 对象转发到窗体的通知。 对于此示例,DataInterest 属性通过 DataInterestMask 枚举定义对 StylusDown、Packets、StylusUp 和 Error 通知的兴趣。
public DataInterestMask DataInterest
{
get
{
return DataInterestMask.StylusDown |
DataInterestMask.Packets |
DataInterestMask.StylusUp |
DataInterestMask.Error;
}
}
当触控笔触摸数字化器表面时,将发出 StylusDown 通知。 发生这种情况时,示例会分配一个数组,该数组用于存储 Stylus 对象的数据包数据。 StylusDown 方法中的 StylusDownData 将添加到数组中,并将该数组插入到哈希表中,方法是使用 Stylus 对象的 Id 属性作为键。
public void StylusDown(RealTimeStylus sender, StylusDownData data)
{
ArrayList collectedPackets = new ArrayList();
collectedPackets.AddRange(data.GetData());
myPackets.Add(data.Stylus.Id, collectedPackets);
}
当触控笔在数字化器表面移动时,将发生 数据包 通知。 发生这种情况时,应用程序会将新的 StylusDownData 添加到 Stylus 对象的数据包数组中。 它通过使用 Stylus 对象的 Id 属性作为键来从哈希表中检索触笔的数据包数组来执行此操作。 然后将新的数据包数据插入检索到的数组中。
public void Packets(RealTimeStylus sender, PacketsData data)
{
((ArrayList)(myPackets[data.Stylus.Id])).AddRange(data.GetData());
}
当笔离开数字化器表面时,将发出 StylusUp 通知。 发生此通知时,该示例将从哈希表中检索此 Stylus 对象的数据包数组-将其从不再需要的哈希表中删除,添加新的数据包数据,并使用数据包数据数组创建新的 Stroke 对象 stroke
。
public void StylusUp(RealTimeStylus sender, StylusUpData data)
{
ArrayList collectedPackets = (ArrayList)myPackets[data.Stylus.Id];
myPackets.Remove(data.Stylus.Id);
collectedPackets.AddRange(data.GetData());
int[] packets = (int[])(collectedPackets.ToArray(typeof(int)));
TabletPropertyDescriptionCollection tabletProperties =
myRealTimeStylus.GetTabletPropertyDescriptionCollection(data.Stylus.TabletContextId);
Stroke stroke = myInk.CreateStroke(packets, tabletProperties);
if (stroke != null)
{
stroke.DrawingAttributes.Color = myDynamicRenderer.DrawingAttributes.Color;
stroke.DrawingAttributes.Width = myDynamicRenderer.DrawingAttributes.Width;
}
}
有关更可靠地使用 RealTimeStylus 类(包括使用自定义插件创建)的示例,请参阅 RealTimeStylus 插件示例。
相关主题