Condividi tramite


Esempio di raccolta ink RealTimeStylus

Questa applicazione illustra la raccolta e il rendering dell'input penna quando si usa la classe RealTimeStylus .

Progetto InkCollection

Questo esempio è costituito da una singola soluzione che contiene un progetto, InkCollection. L'applicazione definisce lo InkCollection spazio dei nomi che contiene una singola classe, denominata InkCollectionanche . La classe eredita dalla classe Form e implementa l'interfaccia IStylusAsyncPlugin .

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

La classe InkCollection definisce un set di costanti private usate per specificare vari spessori input penna. La classe dichiara anche istanze private della classe RealTimeStylus, , myRealTimeStylusla classe DynamicRenderer, myDynamicRenderere la classe myRendererRenderer . DynamicRendereresegue il rendering del tratto attualmente in corso di raccolta. L'oggetto Renderer, myRenderer, esegue il rendering degli oggetti Stroke già raccolti.

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 dichiara anche un oggetto Hashtable , myPacketsche viene usato per archiviare i dati dei pacchetti raccolti da uno o più oggetti Cursor . I valori ID dell'oggetto Stylus vengono usati come chiave hashtable per identificare in modo univoco i dati del pacchetto raccolti per un determinato oggetto Cursor.

Un'istanza privata dell'oggetto Ink , myInk, archivia gli oggetti Stroke raccolti da myRealTimeStylus.

private Hashtable myPackets;
        
private Ink myInk;

Evento di caricamento del modulo

Nel gestore eventi di caricamento per il modulo viene myDynamicRenderer creata un'istanza usando DynamicRenderer che accetta un controllo come argomento e myRenderer viene costruito con un costruttore no-argument.

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

Prestare attenzione al commento che segue l'istanza dei renderer, perché myDynamicRenderer usa i valori predefiniti per DrawingAttributes durante il rendering dell'input penna. Questo è il comportamento standard. Tuttavia, se si desidera assegnare al rendering dell'input penna un aspetto diverso dall'input penna eseguito da myDynamicRenderermyRenderer, è possibile modificare la proprietà DrawingAttributes in myDynamicRenderer. A tale scopo, annullare ilcommentare le righe seguenti prima di compilare ed eseguire l'applicazione.

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

Successivamente, l'applicazione crea l'oggetto RealTimeStylus usato per ricevere notifiche di stilo e aggiunge l'oggetto DynamicRenderer alla coda di notifica plug-in sincrona. In particolare, myRealTimeStylus aggiunge myDynamicRenderer alla proprietà SyncPluginCollection .

    myRealTimeStylus = new RealTimeStylus(this, true);

    myRealTimeStylus.SyncPluginCollection.Add(myDynamicRenderer);

Il modulo viene quindi aggiunto alla coda di notifica plug-in asincrona. In particolare, InkCollection viene aggiunto alla proprietà AsyncPluginCollection . Infine, myRealTimeStylus e sono abilitati e myPackets e myDynamicRenderer myInk vengono create istanze.

    myRealTimeStylus.AsyncPluginCollection.Add(this);

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

Oltre ad associare i gestori di menu per modificare il colore e le dimensioni dell'input penna, è necessario un blocco più breve di codice prima di implementare l'interfaccia. L'esempio deve gestire l'evento Paint del modulo. Nel gestore eventi l'applicazione deve aggiornare myDynamicRenderer perché è possibile che un oggetto Stroke venga raccolto al momento in cui si verifica l'evento Paint. In questo caso, la parte dell'oggetto Stroke che è già stata raccolta deve essere ridisegnata. Il renderer statico viene usato per disegnare nuovamente oggetti Stroke già raccolti. Questi tratti si trovano nell'oggetto Input penna perché vengono posizionati in questo punto, come illustrato nella sezione successiva.

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

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

Implementazione dell'interfaccia IStylusAsyncPlugin

L'applicazione di esempio definisce i tipi di notifiche che ha interesse a ricevere nell'implementazione della proprietà DataInterest . La proprietà DataInterest definisce quindi quali notifiche inoltrano l'oggetto RealTimeStylus al modulo. Per questo esempio, la proprietà DataInterest definisce l'interesse per l'enumerazione StylusDown, Pacchetti, StylusUp e Error tramite l'enumerazione DataInterestMask .

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

La notifica StylusDown si verifica quando la penna tocca la superficie del digitalizzatore. In questo caso, l'esempio alloca una matrice usata per archiviare i dati del pacchetto per l'oggetto Stylus . Il metodo StylusDownData dal metodo StylusDown viene aggiunto alla matrice e la matrice viene inserita nella tabella hash usando la proprietà ID dell'oggetto Stylus come chiave.

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

    collectedPackets.AddRange(data.GetData());

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

La notifica Pacchetti si verifica quando la penna si sposta sulla superficie del digitalizzatore. In questo caso, l'applicazione aggiunge nuovo StylusDownData alla matrice di pacchetti per l'oggetto Stylus . Questa operazione viene eseguita usando la proprietà Id dell'oggetto Stylus come chiave per recuperare la matrice di pacchetti per lo stilo dalla tabella hash. I nuovi dati dei pacchetti vengono quindi inseriti nella matrice recuperata.

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

La notifica StylusUp si verifica quando la penna lascia la superficie del digitalizzatore. Quando si verifica questa notifica, l'esempio recupera la matrice di pacchetti per questo oggetto Stylus dall'oggetto hashtable rimuovendolo dalla tabella hash perché non è più necessario, aggiunge nei nuovi dati del pacchetto e usa la matrice di dati del pacchetto per creare un nuovo oggetto 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;
    } 
}

Per un esempio che mostra un uso più affidabile della classe RealTimeStylus , incluso l'uso della creazione di plug-in personalizzati, vedere Esempio di plug-in RealTimeStylus.

Microsoft.Ink.Renderer

Microsoft.StylusInput.DynamicRenderer

Microsoft.StylusInput.RealTimeStylus

Microsoft.StylusInput.IStylusAsyncPlugin

Accesso e modifica dell'input dello stilo