In the last episode we explored the recognition capabilities of the Tablet PC. We discussed the
two major ways in which recognition can be implemented i.e. synchronous and asynchronous process. We also saw how the synchronous process can be programmed to get ink recognition and we
took a walk through to see how the Visual Studio .NET 2003 and the Tablet PC SDK 1.7 made it simple to implement this feature with a few lines of coding.
Some examples of asynchronous operations can be seen in the functioning of the TIP (Tablet Input Panel). For those of you who have not seen what the Tip is and what it does, here is a brief account of it.
The TIP button (or indicator) appears whenever you hold the pen to any application and on clicking on the button, the Tablet Input Panel appears where you can start inking and clicking on the submit button, the ink gets converted to text and it appears in the application whether it is a Word document or a text document or the text box in a web application. But the interesting fact of the TIP is that as you start writing in ink, the recognition begins and it starts guessing the closest match to the words and on completing the word the correct word is displayed in the lower left of the TIP. Of course there are ways to correct this anomaly if there are spelling errors but that is not the focus of this article. The way in which the ink gets recognized and displayed as text is due to the asynchronous recognition.
Now let us see the core features of asynchronous programming and see how it is implemented and how the coding has to be done to implement asynchronous recognition. To illustrate this sample we will take a very simple example that we saw in the last chapter. In the top half of the screen there was a text box and we had to write in ink and then click on the button to get it recognized and displayed in the same text box.
Now we will focus on the lower half of the screen. We will place a list box just below the inking area and when we start inking in the ink panel the recognition will be done on a character by character basis and displayed in the list box. Finally when we complete writing the whole word we will see the recognized text in the list box and see that we do not see any need to click any buttons to get the ink recognized.
Start Visual Studio .net 2003 and create a windows form application. We will continue from the previous lay out and enhance it. Place a list box and a text box below the text box in the lower half as seen in Figure 1.
Now we will focus on the code.
Remember that for all inking features the following directive needs to be placed at the top of the page along with the other directives.
using
Now we will create the ink overlay variables for the Asynchronous controls so that they can be attached to the strokes and used in the example. The coding is similar to what we had done in the previous episode except that a few lines of code will be added for the asynchronous operation using Delegates.
//defining the inkoverlay for async
privateMicrosoft.Ink.InkOverlaytxtAsyncOverlay;
//defining the strokes for the async text boxes
privateMicrosoft.Ink.StrokestxtAsyncStrokesToRecognize;
//define the overlay for the asynchronous textbox
txtAsyncOverlay=new Microsoft.Ink.InkOverlay(txtAsynchronous.Handle);
txtAsyncOverlay.Enabled=true;
Initiate the strokes that we have created for the Asynchronous control.
//initiate the strokes for the async text box (strokes)
txtAsyncStrokesToRecognize=txtAsyncOverlay.Ink.CreateStrokes();
Initiate the recognizers.
//instantiate the recognizers
foreach(RecognizerrecognizerinnewMicrosoft.Ink.Recognizers()){
if (recognizer.Name== "Microsoft English (US) Handwriting Recognizer")
{
recognizerContext=recognizer.CreateRecognizerContext();
recognizerContext.Strokes=txtAsyncStrokesToRecognize;
}
}
Now we will create delegates. I hope that all of you know what delegates are and we will not discuss this in this episode. What we will focus on is just how and why delegates are used and how they help in asynchronous operations for recognition.
Now when you type this code for registering the delegates you will see that Visual Studio .NET 2003 helps to create the event handler for the delegate. That means any code that is put in the event handler of the delegate will be processed parallely at the time of executing the strokes.
//register the delegates for the strokes
txtAsyncOverlay.Stroke+=newInkCollectorStrokeEventHandler(txtAsyncOverlay_Stroke);
Now we will see later the code that has to be entered in the event handler of txtAsyncOverlay_Stroke.
We will create the delegates for the recognizers and the code will be in the same way as done above. Another event handler will be created.
//register the delegates for the recognizers
if (recognizerContext!=null)
{
recognizerContext.Recognition+=newRecognizerContextRecognitionEventHandler(recognizerContext_Recognition);}
Now let us focus on entering the code for the event handler for the two delegates that we created. Enter the code as seen below. Note that the first part is instantianting the stroke and then adding it to the collection of strokes. Now comes the interesting line of Code "BackgroundRecognize". This is the trick that will perform the asynchronous operation which means that the ink will be recognized after the strokes are entered.
private
{
Strokestroke=e.Stroke;
if ((stroke.DrawingAttributes.RasterOperation!=RasterOperation.MaskPen)
&& (txtOverlay.EditingMode==InkOverlayEditingMode.Ink))
{
txtAsyncStrokesToRecognize.Add(stroke);
recognizerContext.BackgroundRecognize();
}
}
Finally we enter the code for the event handler of the Recognizer context and we show the recognized text in the text box and we will also demonstrate an interesting concept.
Note that we are capturing ink on a stroke wise basis and so as the strokes are entered the list box will capture each stroke and attempt to recognize it. It may give unpredictable results due to the architecture of the recognizer and also upon the language of the
recognizer that we have configured it for. In this example we are configuring it for "English — United States".
Also depending on the way the person writes the ink the strokes are collected in different ways. For example if a person writes the text on a character by character basis then the list box will add the recognized ink on character by character basis. If he writes it
continuously without lifting his pen from the screen then the whole word will be displayed in the list box.
privatevoidrecognizerContext_Recognition(objectsender, RecognizerContextRecognitionEventArgse)
{
//get the current handle of the control which has the focus
if(txtAsyncStrokesToRecognize.Ink.Strokes.Count> 0)
{
lstboxRecognize.Items.Add(e.Text) ;
textBox1.Text=e.Text;
}
}
Now let us run the code and see how the results come out. Press F5 and run the application. Now attempt to write a word on a character by character basis.
The output is seen in the figure below