Tablet PC: Getting started with InkAnalysis – asynchronous analysis

In my last post:

https://blogs.msdn.com/gavingear/archive/2006/09/07/745132.aspx

I demonstrated how to create an InkAnalysis Windows Forms project using the Windows Vista SDK for RC1 and Visual Studio .NET 2005. This application performed basic synchronous handwriting recognition. In this post we’ll modify that application to perform asynchronous handwriting recognition using InkAnalysis.

Here’s a summary of the changes:

1. Add a private InkAnalyzer member to the BasicInkApplication class. This is required because we need to hook up to an InkAnalyzer event, and access the InkAnalyzer object from the event handler

2. Hook up to the InkOverlay.Stroke event so we can add strokes to the InkAnalyzer as they are collected

3. Call InkAnalyzer.BackgroundAnalyze() to kick off asynchronous analysis

4. Hook up to the InkAnalyzer.ResultsUpdated event so we can receive notification of the completion of asynchronous analysis

5. We call InkAnalyzer.Dispose() from the Form.FormClosing event to clean up

Sample Code:

//

// Basic Ink enabled Windows Forms application with

// handwriting recognition using InkAnalyzer

// Gavin Gear - https://blogs.msdn.com/gavingear

// 09/2006

//

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using Microsoft.Ink; // The managed Tablet PC API

namespace BasicInkApplication

{

    public partial class BasicInkApplication : Form

    {

        // The InkOverlay that we'll attach to our Form

        private InkOverlay inkOverlay;

        private InkAnalyzer inkAnalyzer;

        public BasicInkApplication()

        {

            InitializeComponent();

            // Create an InkOverlay object that's attached to the Form

            this.inkOverlay = new InkOverlay(this);

            // Enable the InkOverlay (default is Enabled == false)

            this.inkOverlay.Enabled = true;

            this.inkOverlay.Stroke += new InkCollectorStrokeEventHandler(inkOverlay_Stroke);

            // Create a new InkAnalyzer

            // - Associate with the InkOverlay's Ink object

            // - Send the Form "this" as the synchronizing object

            this.inkAnalyzer = new InkAnalyzer(this.inkOverlay.Ink, this);

            // Hook up to the InkAnalyzer.ResultsUpdated event

            // in order to be notified when BackgroundAnalyze() finishes

            this.inkAnalyzer.ResultsUpdated +=

                new ResultsUpdatedEventHandler(inkAnalyzer_ResultsUpdated);

            // The InkOverlay needs to be disposed due to unmanaged resources

            // used by the InkOverlay

            this.FormClosing += new FormClosingEventHandler(BasicInkApplication_FormClosing);

        }

        // The InkOverlay.Stroke event is fired after a new stroke is

        // collected by the InkOverlay

        void inkOverlay_Stroke(object sender, InkCollectorStrokeEventArgs e)

        {

            // We have a new stroke, add it to the InkAnalyzer

            this.inkAnalyzer.AddStroke(e.Stroke);

        }

        // Clean up unmanaged resources

        void BasicInkApplication_FormClosing(object sender, FormClosingEventArgs e)

        {

          this.inkOverlay.Dispose();

            this.inkAnalyzer.Dispose(); // Free the unmanaged resources

        }

        private void buttonRecognize_Click(object sender, EventArgs e)

        {

            // Kick off asynchronous analysis

            // Should check that BackgroundAnalyze() returns true here

            this.inkAnalyzer.BackgroundAnalyze();

        }

        // This event is fired when analysis is complete

        void inkAnalyzer_ResultsUpdated(object sender, ResultsUpdatedEventArgs e)

        {

            // Note: Should check: e.Status.Successful == true

            // here to confirm BackgroundAnalyze() was successful

            MessageBox.Show(this.inkAnalyzer.GetRecognizedString());

        }

    }

}

 

So that’s a very basic look at asynchronous analysis using InkAnalyzer.BackgroundAnalyze(). This is enough to get you started!

Note that the InkAnalysis will do the synchronization FOR YOU when you supply an object which Implements ISynchronizeInvoke (That’s the case for Form which is a descendent of Control). This means our event handlers get called on the thread which created the InkAnalyzer. This can make life a lot easier on you, and can help you avoid threading related bugs.

That’s it for now…

See ya,

Gavin