O modelo de objeto de tinta: Windows Forms e COM versus WPF
Há basicamente três plataformas que dão suporte a tinta digital: a plataforma Tablet PC Windows Forms, a plataforma Tablet PC COM e o Windows Presentation Foundation (WPF) plataforma. As plataformas Windows Forms e COM compartilham um modelo de objeto semelhantes, mas o modelo de objetos para a plataforma WPF é significativamente diferente. Este tópico discute as diferenças em um alto nível para que os desenvolvedores que tem trabalhado com um modelo de objetos possam entender o outro.
Ativando tinta em um aplicativo
Todas as três plataformas vêm com objetos e controles que permitem que um aplicativo receba entrada de uma caneta digitalizadora. O Windows Forms e as plataformas COM acompanham InkPicture, InkEdit, InkOverlay e InkCollector classes. InkPicture e InkEdit são controles que podem ser adicionados a um aplicativo para coletar tinta. O InkOverlay e InkCollector podem ser anexados a uma janela existente para ativar tinta nas janelas e controles personalizados.
A plataforma WPF inclui o controle InkCanvas. Você pode adicionar um InkCanvas ao seu aplicativo e começar a coleta de tinta imediatamente. Com o InkCanvas, o usuário pode copiar, selecionar e redimensionar a tinta. Você pode adicionar outros controles ao InkCanvas, e o usuário pode fazer manuscritos sobre esses controles, também. Você pode criar um controle personalizado ativado para tinta, adicionando-lhe um InkPresenter e coletando seus pontos de caneta.
A tabela a seguir lista onde você pode saber mais sobre a ativação de tinta em um aplicativo:
Para fazer isso... |
Na plataforma WPF…. |
Nas Plataformas Windows Forms/COM… |
---|---|---|
Adicionar um controle com ativação de tinta a um aplicativo |
Consulte Getting Started with Ink. |
Consulte Auto Claims Form Sample. |
Ativar a tinta em um controle personalizado |
Consulte Criar um controle de entrada à tinta. |
Consulte Ink Clipboard Sample. |
Dados de tinta
Nas plataformas Windows Forms e COM, InkCollector, InkOverlay, InkEdit, e InkPicture expõem um objeto Microsoft.Ink.Ink. O objeto Ink contém os dados para um ou mais objetos Microsoft.Ink.Stroke e expõe métodos e propriedades comuns para gerenciar e manipular esses traços. O objeto Ink gerencia a vida útil dos traços que ele contém; o objeto Ink cria e exclui os traços que ele possui. Cada Stroke possui um identificador que é exclusivo dentre de seu objeto-pai Ink.
Na plataforma WPF, a classe System.Windows.Ink.Stroke possui e gerencia seu próprio tempo de vida. Um grupo de objetos Stroke podem ser coletado juntos em um StrokeCollection, que fornece métodos para operações comuns no gerenciamento dos dados de tinta tais como as teste de clique, apagar, transformar e a serialização de tinta. Um Stroke podem pertencer a zero, um ou mais objetos StrokeCollection em qualquer momento. Em vez de possuir um objeto Microsoft.Ink.Ink, o InkCanvas e InkPresenter contêm um System.Windows.Ink.StrokeCollection.
O par de ilustrações a seguir compara os modelos de objeto de dados de tinta. Nas plataformas Windows Forms e COM, o objeto Microsoft.Ink.Ink limita o tempo de vida dos objetos Microsoft.Ink.Stroke, e os pacotes da caneta pertencem aos traços individuais. Dois ou mais traços podem fazer referência ao mesmo objeto Microsoft.Ink.DrawingAttributes, conforme mostrado na ilustração a seguir.
Na WPF, cada System.Windows.Ink.Stroke é um objeto Common Language Runtime que existe enquanto algo fizer uma referência a ele. Cada Stroke referencia um objeto StylusPointCollection e System.Windows.Ink.DrawingAttributes, que também são objetos Common Language Runtime.
A tabela a seguir compara como realizar algumas tarefas comuns na plataforma WPF e nas plataformas Windows Forms e COM.
Tarefa |
Windows Presentation Foundation |
Windows Forms e COM |
---|---|---|
Salvar tinta |
||
Carregar tinta |
Crie um StrokeCollection com o construtor StrokeCollection.StrokeCollection(Stream). |
|
Teste de clique |
||
Copiar tinta |
||
Colar tinta |
||
Acessar propriedades personalizadas em uma coleção de traços |
AddPropertyData (as propriedades são armazenadas internamente e acessadas através de AddPropertyData, RemovePropertyData e ContainsPropertyData) |
Usar ExtendedProperties |
O compartilhamento de tinta entre plataformas
Embora as plataformas tenham modelos de objeto diferentes para os dados de tinta, o compartilhamento de dados entre as plataformas é muito fácil. Os exemplos a seguir salvam a tinta de um aplicativo Windows Forms e carregam-na em um aplicativo 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);
}
Os exemplos a seguir salvam a tinta de um aplicativo Windows Presentation Foundation e carregam-na em um aplicativo Windows Forms.
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());
}
Eventos de caneta digitalizadora
O InkOverlay, InkCollector e InkPicture nas plataformas Windows Forms e COM recebem eventos quando o usuário fornece dados da caneta. O InkOverlay ou InkCollector é anexado a uma janela ou um controle, e pode inscrever-se para receber os eventos gerados pelos dados de entrada do tablet. O thread em que esses eventos ocorrem depende se os eventos são gerados com uma caneta, um mouse, ou programaticamente. Para obter mais informações sobre uso de threads em relação a esses eventos, consulte General Threading Considerations e Threads on Which an Event Can Fire.
Na plataforma Windows Presentation Foundation, a classe UIElement tem eventos para entrada de caneta. Isso significa que cada controle expõe o conjunto completo de eventos de caneta. Os eventos de caneta tem pares de eventos com tunelamento/bolheamento e sempre ocorrem no thread do aplicativo. Para obter mais informações, consulte Visão geral sobre eventos roteados.
O diagrama a seguir compara os modelos de objeto para as classes que geram eventos de caneta. O modelo de objeto Windows Presentation Foundation mostra somente os eventos bolheantes, não os eventos tunelantes correspondentes.
Dados da caneta
Todas as três plataformas fornecem meios para interceptar e manipular os dados provenientes de uma caneta digitalizadora. Nas plataformas Windows Forms e COM, isso é conseguido ao criar um RealTimeStylus, anexar uma janela ou controle a ela, e criar uma classe que implementa as interfaces IStylusSyncPlugin ou IStylusAsyncPlugin. O plug-in personalizado, em seguida, é adicionado à coleção de plug-ins do RealTimeStylus. Para obter mais informações sobre este modelo de objeto, consulte Architecture of the StylusInput APIs.
Na plataforma WPF, a classe UIElement expõe um conjunto de plug-ins, semelhante a RealTimeStylus no design. Para interceptar dados da caneta, crie uma classe que herda de StylusPlugIn e adicione o objeto à coleção StylusPlugIns do UIElement. Para obter mais informações sobre essa interação, consulte Interceptação de entrada a partir do Stylus.
Em todas as plataformas, um pool de threads recebe os dados de tinta através dos eventos de caneta e os envia para o thread do aplicativo. Para obter mais informações sobre uso de threads nas plataformas COM e Windows, consulte Threading Considerations for the StylusInput APIs. Para obter mais informações sobre o uso de threads no software de Apresentação do Windows, consulte O modelo de encadeamento de tinta.
A ilustração a seguir compara os modelos de objeto para as classes que recebem dados da caneta no pool de threads de caneta.