Ink 对象模型:Windows 窗体和 COM 与 WPF 之比较
更新:2007 年 11 月
主要有三个支持数字墨迹的平台:Tablet PC Windows 窗体平台、Tablet PC COM 平台和 Windows Presentation Foundation (WPF) 平台。 Windows 窗体平台和 COM 平台的对象模型非常类似,但 WPF 平台的对象模型有根本的不同。 本主题从较高层次讨论其区别,以便只使用一种对象模型的开发人员可以更好地了解其他对象模型。
在应用程序中启用墨迹
所有三个平台都附带了对象和控件,这些对象和控件使应用程序可以接收 Tablet 笔的输入。 Windows 窗体平台和 COM 平台附带了 InkPicture、InkEdit、InkOverlay 和 InkCollector 类。InkPicture 和 InkEdit 是可以添加到应用程序以收集墨迹的控件。 InkOverlay 和 InkCollector 可以附加到现有的窗口,以便对窗口和自定义控件启用墨迹。
WPF 平台包含 InkCanvas 控件。 可以将 InkCanvas 添加到应用程序中并立即开始收集墨迹。使用 InkCanvas,用户可以复制、选择墨迹和调整墨迹大小。 也可以将其他控件添加到 InkCanvas,用户可以在这些控件上进行手写。 可以通过将 InkPresenter 添加到自定义控件并收集其手写笔接触点,创建支持墨迹的自定义控件。
下表列出了在何处可以了解有关在应用程序中启用墨迹的更多信息:
若要执行此操作... |
在 WPF 平台上… |
在 Windows 窗体/COM 平台上… |
---|---|---|
将支持墨迹的控件添加到应用程序中 |
请参见墨迹入门 |
|
在自定义控件上启用墨迹 |
请参见创建墨迹输入控件 |
墨迹数据
在 Windows 窗体平台和 COM 平台上,InkCollector、InkOverlay、InkEdit 和 InkPicture 都公开一个 Microsoft.Ink.Ink 对象。Ink 对象包含一个或多个 Microsoft.Ink.Stroke 对象的数据,并公开常用方法和属性,以管理和操作这些笔画。 Ink 对象管理所包含笔画的生命周期;Ink 对象创建并删除所拥有的笔画。 每个 Stroke 在其父 Ink 对象中都有一个唯一标识符。
在 WPF 平台上,System.Windows.Ink.Stroke 类拥有并管理自己的生命周期。可以将一组 Stroke 对象收集到一个 StrokeCollection 中,以提供常用墨迹数据管理操作(如命中测试、擦除、转换和序列化墨迹)方法。在任意给定时刻,Stroke 可以属于零个、一个或多个 StrokeCollection 对象。 InkCanvas 和 InkPresenter 包含 System.Windows.Ink.StrokeCollection,而不是 Microsoft.Ink.Ink 对象。
下面两个插图对墨迹数据对象模型进行了比较。 在 Windows 窗体平台和 COM 平台上,Microsoft.Ink.Ink 对象约束 Microsoft.Ink.Stroke 对象的生命周期,且手写笔数据包属于单个笔画。 如下图所示,两个或更多笔画可以引用同一 Microsoft.Ink.DrawingAttributes 对象。
在 WPF 上,每个 System.Windows.Ink.Stroke 都是一个常用语言运行时对象,只要有对象引用就会存在。 每个 Stroke 均引用 StylusPointCollection 和 System.Windows.Ink.DrawingAttributes 对象,这两个对象都是常用语言运行时对象。
下表对在 WPF 平台、Windows 窗体平台和 COM 平台上完成某些常用任务的方法进行了比较。
任务 |
Windows Presentation Foundation |
Windows 窗体和 COM |
---|---|---|
保存墨迹 |
||
加载墨迹 |
使用 StrokeCollection.StrokeCollection(Stream) 构造函数创建 StrokeCollection |
|
命中测试 |
||
复制墨迹 |
||
粘贴墨迹 |
||
访问笔画集合的自定义属性 |
AddPropertyData(这些属性存储在内部,并通过 AddPropertyData、RemovePropertyData 和 ContainsPropertyData 访问) |
在平台之间共享墨迹
虽然各平台的墨迹数据对象模型不同,但是在各平台之间共享数据却非常简单。下面的示例保存 Windows 窗体应用程序中的墨迹,并将该墨迹加载到 Windows Presentation Foundation 应用程序。
Imports Microsoft.Ink
Imports System.Drawing
...
'/ <summary>
'/ Saves the digital ink from a Windows Forms application.
'/ </summary>
'/ <param name="inkToSave">An Ink object that contains the
'/ digital ink.</param>
'/ <returns>A MemoryStream containing the digital ink.</returns>
Function SaveInkInWinforms(ByVal inkToSave As Ink) As MemoryStream
Dim savedInk As Byte() = inkToSave.Save()
Return New MemoryStream(savedInk)
End Function 'SaveInkInWinforms
using Microsoft.Ink;
using System.Drawing;
...
/// <summary>
/// Saves the digital ink from a Windows Forms application.
/// </summary>
/// <param name="inkToSave">An Ink object that contains the
/// digital ink.</param>
/// <returns>A MemoryStream containing the digital ink.</returns>
MemoryStream SaveInkInWinforms(Ink inkToSave)
{
byte[] savedInk = inkToSave.Save();
return (new MemoryStream(savedInk));
}
Imports System.Windows.Ink
...
'/ <summary>
'/ Loads digital ink into a StrokeCollection, which can be
'/ used by a WPF application.
'/ </summary>
'/ <param name="savedInk">A MemoryStream containing the digital ink.</param>
Public Sub LoadInkInWPF(ByVal inkStream As MemoryStream)
strokes = New StrokeCollection(inkStream)
End Sub 'LoadInkInWPF
using System.Windows.Ink;
...
/// <summary>
/// Loads digital ink into a StrokeCollection, which can be
/// used by a WPF application.
/// </summary>
/// <param name="savedInk">A MemoryStream containing the digital ink.</param>
public void LoadInkInWPF(MemoryStream inkStream)
{
strokes = new StrokeCollection(inkStream);
}
下面的示例保存 Windows Presentation Foundation 应用程序中的墨迹,并将该墨迹加载到 Windows 窗体应用程序。
Imports System.Windows.Ink
...
'/ <summary>
'/ Saves the digital ink from a WPF application.
'/ </summary>
'/ <param name="inkToSave">A StrokeCollection that contains the
'/ digital ink.</param>
'/ <returns>A MemoryStream containing the digital ink.</returns>
Function SaveInkInWPF(ByVal strokesToSave As StrokeCollection) As MemoryStream
Dim savedInk As New MemoryStream()
strokesToSave.Save(savedInk)
Return savedInk
End Function 'SaveInkInWPF
using System.Windows.Ink;
...
/// <summary>
/// Saves the digital ink from a WPF application.
/// </summary>
/// <param name="inkToSave">A StrokeCollection that contains the
/// digital ink.</param>
/// <returns>A MemoryStream containing the digital ink.</returns>
MemoryStream SaveInkInWPF(StrokeCollection strokesToSave)
{
MemoryStream savedInk = new MemoryStream();
strokesToSave.Save(savedInk);
return savedInk;
}
Imports Microsoft.Ink
Imports System.Drawing
...
'/ <summary>
'/ Loads digital ink into a Windows Forms application.
'/ </summary>
'/ <param name="savedInk">A MemoryStream containing the digital ink.</param>
Public Sub LoadInkInWinforms(ByVal savedInk As MemoryStream)
theInk = New Ink()
theInk.Load(savedInk.ToArray())
End Sub 'LoadInkInWinforms
using Microsoft.Ink;
using System.Drawing;
...
/// <summary>
/// Loads digital ink into a Windows Forms application.
/// </summary>
/// <param name="savedInk">A MemoryStream containing the digital ink.</param>
public void LoadInkInWinforms(MemoryStream savedInk)
{
theInk = new Ink();
theInk.Load(savedInk.ToArray());
}
Tablet 笔的事件
Windows 窗体平台和 COM 平台上的 InkOverlay、InkCollector 和 InkPicture 在用户输入笔数据时接收事件。 InkOverlay 或 InkCollector 附加到窗口或控件中,可以订阅由 Tablet 输入数据引发的事件。 这些事件发生时所在的线程取决于该事件是由笔、鼠标还是以编程方式引发。 有关与这些事件相关的线程的更多信息,请参见General Threading Considerations和Threads on Which an Event Can Fire。
在 Windows Presentation Foundation 平台上,UIElement 类具有笔输入事件。这意味着每个控件都公开完整的手写笔事件集。 手写笔事件具有隧道/冒泡事件对,并始终发生于应用程序线程上。有关更多信息,请参见路由事件概述。
下图对引发手写笔事件的类的对象模型进行了比较。Windows Presentation Foundation 对象模型只显示冒泡事件,不显示对应的隧道事件。
笔数据
所有三个平台都为您提供了截获和操作来自 Tablet 笔的数据的方法。 在 Windows 窗体平台和 COM 平台上,这通过创建一个 RealTimeStylus、为其附加窗口或控件并创建实现 IStylusSyncPlugin 或 IStylusAsyncPlugin 接口的类来完成。随后,将自定义插件添加到 RealTimeStylus 的插件集合中。有关此对象模型的更多信息,请参见 Architecture of the StylusInput APIs。
在 WPF 平台上,UIElement 类公开一个插件集合,在设计上类似于 RealTimeStylus。 若要截获笔数据,请创建一个从 StylusPlugIn 继承的类,并将该对象添加到 UIElement 的 StylusPlugIns 集合中。有关此交互的更多信息,请参见截获手写笔输入。
在所有平台上,线程池通过手写笔事件接收墨迹数据,并将其发送到应用程序线程。 有关 COM 和 Windows 平台上线程处理的更多信息,请参见 Threading Considerations for the StylusInput APIs。 有关 Windows Presentation 软件上线程处理的更多信息,请参见 墨迹线程处理模型。
下图对接收笔线程池中的笔数据的类的对象模型进行了比较。