Partager via


Exemple de collection d’encres RealTimeStylus

Cette application illustre la collection d’encre et le rendu lors de l’utilisation de la classe RealTimeStylus .

Le projet InkCollection

Cet exemple se compose d’une solution unique qui contient un projet, InkCollection. L’application définit l’espace InkCollection de noms qui contient une seule classe, également appelée InkCollection. La classe hérite de la classe Form et implémente l’interface IStylusAsyncPlugin .

namespace InkCollection
{
    public class InkCollection : Form, IStylusAsyncPlugin
    {
        //...
      

La classe InkCollection définit un ensemble de constantes privées utilisées pour spécifier différentes épaisseurs d’encre. La classe déclare également des instances privées de la classe RealTimeStylus, myRealTimeStylus, de la classe DynamicRenderer et myDynamicRendererde la classe myRendererRenderer . DynamicRenderer restitue le trait en cours de collecte. L’objet Renderer, myRenderer, restitue les objets Stroke qui ont déjà été collectés.

private const float ThinInkWidth = 10;
private const float MediumInkWidth = 100;
private const float ThickInkWidth = 200;

private RealTimeStylus myRealTimeStylus;

private DynamicRenderer myDynamicRenderer;
private Renderer myRenderer;

La classe déclare également un objet Hashtable , myPackets, qui est utilisé pour stocker les données de paquets collectées par un ou plusieurs objets Cursor . Les valeurs Id de l’objet Stylus sont utilisées comme clé de hachage pour identifier de manière unique les données de paquets collectées pour un objet Cursor donné.

Un instance privé de l’objet Ink, myInk, stocke les objets Stroke collectés par myRealTimeStylus.

private Hashtable myPackets;
        
private Ink myInk;

Événement Form Load

Dans le gestionnaire d’événements Load du formulaire, myDynamicRenderer est instancié à l’aide du DynamicRenderer qui prend un contrôle comme argument et myRenderer est construit avec un constructeur sans argument.

private void InkCollection_Load(object sender, System.EventArgs e)
{
    myDynamicRenderer = new DynamicRenderer(this);
    myRenderer = new Renderer();
    // ...

Faites attention au commentaire qui suit l’instanciation des convertisseurs, car myDynamicRenderer utilise les valeurs par défaut pour DrawingAttributes lors du rendu de l’entrée manuscrite. Il s’agit d’un comportement standard. Toutefois, si vous souhaitez donner à l’entrée manuscrite une myDynamicRenderer apparence différente de celle rendue par myRenderer, vous pouvez modifier la propriété DrawingAttributes sur myDynamicRenderer. Pour ce faire, supprimez les marques de commentaire suivantes avant de générer et d’exécuter l’application.

    // myDynamicRenderer.DrawingAttributes.PenTip = PenTip.Rectangle;
    // myDynamicRenderer.DrawingAttributes.Height = (.5F)*MediumInkWidth;
    // myDynamicRenderer.DrawingAttributes.Transparency = 128;

Ensuite, l’application crée l’objet RealTimeStylus utilisé pour recevoir des notifications de stylet et ajoute l’objet DynamicRenderer à la file d’attente de notification de plug-in synchrone. Plus précisément, myRealTimeStylus ajoute myDynamicRenderer à la propriété SyncPluginCollection .

    myRealTimeStylus = new RealTimeStylus(this, true);

    myRealTimeStylus.SyncPluginCollection.Add(myDynamicRenderer);

Le formulaire est ensuite ajouté à la file d’attente de notification de plug-in asynchrone. Plus précisément, InkCollection est ajouté à la propriété AsyncPluginCollection . Enfin, myRealTimeStylus et myDynamicRenderer sont activés, et myPackets et myInk sont instanciés.

    myRealTimeStylus.AsyncPluginCollection.Add(this);

    myRealTimeStylus.Enabled = true;
    myDynamicRenderer.Enabled = true;  
      
    myPackets = new Hashtable();
    myInk = new Ink();
}

Outre le raccordement des gestionnaires de menus pour modifier la couleur et la taille de l’encre, un bloc de code supplémentaire est nécessaire avant d’implémenter l’interface. L’exemple doit gérer l’événement Paint du formulaire. Dans le gestionnaire d’événements, l’application doit s’actualiser myDynamicRenderer , car il est possible qu’un objet Stroke soit collecté au moment où l’événement Paint se produit. Dans ce cas, la partie de l’objet Stroke qui a déjà été collectée doit être redessinée. Le renderer statique est utilisé pour dessiner à nouveau les objets Stroke qui ont déjà été collectés. Ces traits se trouvent dans l’objet Ink , car ils y sont placés lorsqu’ils sont dessinés, comme indiqué dans la section suivante.

private void InkCollection_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
    myDynamicRenderer.Refresh();

    myRenderer.Draw(e.Graphics, myInk.Strokes);
} 

Implémentation de l’interface IStylusAsyncPlugin

L’exemple d’application définit les types de notifications qu’elle a intérêt à recevoir dans l’implémentation de la propriété DataInterest . La propriété DataInterest définit donc les notifications que l’objet RealTimeStylus transmet au formulaire. Pour cet exemple, la propriété DataInterest définit l’intérêt pour les notifications StylusDown, Packets, StylusUp et Error via l’énumération DataInterestMask .

public DataInterestMask DataInterest
{
    get
    {
        return DataInterestMask.StylusDown |
               DataInterestMask.Packets |
               DataInterestMask.StylusUp |
               DataInterestMask.Error;
    }
}

La notification StylusDown se produit lorsque le stylet touche la surface du numériseur. Dans ce cas, l’exemple alloue un tableau utilisé pour stocker les données de paquet pour l’objet Stylus . Le StylusDownData de la méthode StylusDown est ajouté au tableau et le tableau est inséré dans la table de hachage à l’aide de la propriété Id de l’objet Stylus comme clé.

public void StylusDown(RealTimeStylus sender, StylusDownData data)
{
    ArrayList collectedPackets = new ArrayList();

    collectedPackets.AddRange(data.GetData());

    myPackets.Add(data.Stylus.Id, collectedPackets);
}

La notification Packets se produit lorsque le stylet se déplace sur la surface du numériseur . Dans ce cas, l’application ajoute un nouveau StylusDownData dans le tableau de paquets pour l’objet Stylus . Pour ce faire, il utilise la propriété Id de l’objet Stylus comme clé pour récupérer le tableau de paquets pour le stylet à partir de la table de hachage. Les nouvelles données de paquets sont ensuite insérées dans le tableau récupéré.

public void Packets(RealTimeStylus sender, PacketsData data)
{
    ((ArrayList)(myPackets[data.Stylus.Id])).AddRange(data.GetData());
}

La notification StylusUp se produit lorsque le stylet quitte la surface du numériseur. Lorsque cette notification se produit, l’exemple récupère le tableau de paquets de cet objet Stylus à partir de la table de hachage en le supprimant de la table de hachage car il n’est plus nécessaire, ajoute les nouvelles données de paquets et utilise le tableau de données de paquets pour créer un nouvel objet 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;
    } 
}

Pour obtenir un exemple montrant une utilisation plus robuste de la classe RealTimeStylus , y compris l’utilisation de la création de plug-ins personnalisés, consultez Exemple de plug-in RealTimeStylus.

Microsoft.Ink.Renderer

Microsoft.StylusInput.DynamicRenderer

Microsoft.StylusInput.RealTimeStylus

Microsoft.StylusInput.IStylusAsyncPlugin

Accès et manipulation d’entrée de stylet