Introduction to Ink-Enabled Applications

 Download CD Content

In this chapter, we build our first ink-enabled applications using VB .NET. We also use source code for C# in this chapter so that you can see the differences and similarities between the languages. For the remaining chapters, we provide source code in VB .NET, but if you prefer C#, it won't take you very long to convert the samples.

  Note 

The source code for the projects are located on the CD-ROM in the PROJECTS folder. You can either type them in as you go or you can copy the projects from the CD-ROM to your hard drive for editing.

Introduction to Ink Controls

In Chapter 12, Obtaining the Tablet PC SDK, we looked at the InkEdit and InkPicture controls. Now, in this chapter, we learn how to utilize the controls to build fully aware ink applications.

The InkPicture and InkEdit controls allow a developer to quickly add ink capabilities to an application. Depending on the needs for a given project, a developer may need the ability to have ink conversion to text, ink for annotating an existing image, or countless other variations. These two controls provide enough functionality to take care of most of the projects you will develop.

Differences between the Controls

The InkEdit control was derived from the standard RichTextBox class and is the control of choice when you want to perform handwriting recognition. By default, the control recognizes the text as you enter it and automatically displays it within the text display area. If you are using a keyboard, you can also enter text into the control, which provides most of the functionality of the RichTextBox. In addition to collecting ink and recognizing and displaying it in text form, the InkEdit control also allows you to display ink as an embedded object, with text formatting options such as underline.

Like the InkEdit control, the InkPicture control is also derived from a standard control. This time, it's the Picture class and it offers an area on which you can annotate. This control is most often used when you do not have a need for ink recognition. Popular uses include capturing signatures, or because it includes the ability to display an image that the user can draw on, it can be used for marking up a scanned form or even drawing. The control accepts a variety of formats, such as jpg, bmp, gif, or png.

Using the InkEdit Control

As was mentioned previously, the InkEdit control was derived from the RichTextBox class. In its default state, the control automatically captures ink, recognizes the handwriting, 'erases' the ink, and then displays the recognized text inside the text box. Interestingly, the handwriting is not really erased, and you can alter between the recognized text and the handwritten information at runtime. Recognition occurs very quickly and allows the user to enter relatively large amounts of information.

Creating a Project

To create a project with the InkEdit control, you need to create a new Windows Forms application and then add it to your Toolbox. Follow these steps to add the control to the toolbox:

  1. Create a new project.
  2. Right-click on the Toolbox.
  3. Select Customize.
  4. Select the .NET Framework Components tab.
  5. Check InkEdit and then click OK.

      Note 

    There is another way that you can access these controls. Instead of adding them to your Toolbox, you can reference and create it in code. However, it's much easier to add them to the Toolbox.

After you have the InkEdit control in the Toolbox, you can add it to your form as quickly as you can to any standard application. To add an instance of the InkEdit control to your form, select the InkEdit control in your Toolbox, and then draw a rectangle region on your form. The size you draw the control is very important because the inkable region is located within the control itself. As with much of Tablet PC development, user interface design is important. If the control is too small, it is difficult for the user to write within its boundaries and the resulting recognition will not be very good. At a minimum, you should size the control to allow a few words and preferably more.

As a reminder, the InkEdit control automatically collects ink and gestures (a sort of shorthand that we discuss in greater detail in Chapter 18, Using Gestures to Control Tablet Media Player). This can be a problem if you are developing only on a desktop PC because you do not have the ability to draw within the control. You can use your mouse for input by adding a single line of code:

InkEdit1.UseMouseForInput = True

Of course, if you are developing on a Tablet PC, this will not be an issue. Either way, after you have added the control to a form, you can run the application in the IDE. Once started, you can write on the InkEdit control. As you can see, the control already provides the ability to write on it without a single line of code (unless you set it up to handle mouse input, which is discussed above) and also converts ink to text automatically. Figures 13.1 and 13.2 display an example of ink and the resulting text.

click to expand
Figure 13.1: Ink being entered.


Figure 13.2: Conversion has taken place.

You can change many aspects of how the InkEdit control recognizes ink. For example, you have the ability to alter the size and position of ink into the control. By setting various properties, you could quickly alter the control to capture a signature or write a handwritten letter. The properties are quite simple, and are discussed in the following sections.

Property Description

This section details the properties available for InkEdit.

Active X Only

We'll look at the properties that are specific to the Active X control first.

Appearance: Returns or sets a value that determines whether the control appears flat or 3D

BackColor: Returns or sets the background color for the control

BorderStyle: Returns or sets a value that determines whether the control has a border

DisableNoScroll: Returns or sets a value that determines whether scroll bars in the control are disabled

DragIcon: Returns or sets the icon that appears as the pointer in a drag-and-drop operation

Font: Returns or sets the font of the text that the control displays

HWnd: Returns the window handle to which the control is bound

Locked: Returns or sets a value that specifies whether the control is read-only

MaxLength: Returns or sets a value indicating whether an InkEdit control can hold a maximum number of characters and, if so, specifies the maximum number of characters

MouseIcon: Returns or sets the current custom mouse icon

MousePointer: Returns or sets a value that indicates the type of mouse pointer that appears when the mouse is over a particular part of the control

MultiLine: Returns or sets a value that indicates whether this is a multiline control

ScrollBars: Returns or sets the type of scroll bars that appear in the control

SelAlignment: Returns or sets the alignment to apply to the current selection or insertion point

SelBold: Returns or sets a value that specifies whether the font style of the currently selected text in the control is bold

SelCharOffset: Returns or sets whether text in the control appears on the baseline, as a superscript, or as a subscript

SelColor: Returns or sets the text color of the current text selection or insertion point

SelFontName: Returns or sets the font name of the selected text within the control

SelFontSize: Returns or sets the font size of the selected text within the control

SelItalic: Returns or sets a value that specifies whether the font style of the currently selected text in the control is italic

SelLength: Returns or sets the number of characters that are selected in the control

SelRTF: Returns or sets the currently selected Rich Text Format (RTF) formatted text in the control

SelStart: Returns or sets the starting point of the text that is selected in the text box

SelText: Returns or sets the selected text within the control

SelUnderline: Returns or sets a value that specifies whether the font style of the currently selected text in the control is underlined

Text: Returns or sets the current text in the text box

TextRTF: Returns or sets the text of the control, including all Rich Text Format (RTF) codes

Managed Library Only

The Managed Library has its own set of properties.

CreateParams: Returns the required creation parameters when the control handle is created

Cursor: Returns or sets the cursor that appears when the mouse pointer is over the control

DrawingAttributes: Returns or sets the drawing attributes to apply to ink as it is drawn

  Note 

This property behaves differently than the DefaultDrawingAttributes property of the InkCollector object, the InkOverlay object, and the InkPicture control.Whereas the DefaultDrawingAttributes property specifies the drawing attributes that are applied to a new cursor, the DrawingAttributes property specifies the drawing attributes for ink that is yet to be collected by the InkEdit control.

Enabled: Set to True or False to enable or disable

General

There are properties that are available for both the Active X and Managed Libraries.

Factoid: Returns or sets the factoid that a recognizer uses to constrain its search for the recognition result

InkInsertMode: Returns or sets the value that specifies how ink is collected when drawn on the control

InkMode: Returns or sets a value that specifies whether ink collection is disabled, ink is collected, or ink and gestures are collected

RecoTimeout: Returns or sets the number of milliseconds after an ink stroke has ended that text recognition begins

Recognizer: Returns or sets the recognizer to use for recognition

SelInks: Returns or sets the array of embedded Ink objects (if displayed as ink) that the current selection contains

SelInksDisplayMode: Returns or sets a value that allows toggling the appearance of the selection between ink and text

Status: Returns a value that specifies whether the control is idle, collecting ink, or recognizing ink

UseMouseForInput: Returns or sets a value that indicates whether the mouse is used as an input device

Having Fun with Properties

With so many properties that we have access to, there is a great deal of fun we can have with them. Before we go further, we need to add the following line to the top of the project:

Imports Microsoft.Ink

Next, we are going to add a series of buttons that will allow us to set some of the various properties for the control. Add the following buttons with their respective properties (see Table 13.1) and place them on the form using Figure 13.3 as an example.

click to expand
Figure 13.3: Button layout for our example.

Table 13.1: Adding buttons and properties to our example

Name

Text

btnDisplayAsInk

Display as Ink

btnDisplayAsText

Display as Text

btnInsertAsInk

Insert as Ink

btnInsertAsText

Insert as Text

btnIncreaseRecoTime

+ Reco Time

btnSubRecoTime

- Reco Time

You can probably tell what each of these controls will be used for by their names and text properties. We'll begin with btnDisplayAsInk. Double-click the control to open the Code Editor and create the btnDisplay_Click event procedure. We need to add two lines to the event:

InkEdit1.SelectAll()
InkEdit1.SelInksDisplayMode = InkDisplayMode.Ink

The previous code begins by selecting all of the text located with InkEdit1, which was added earlier in the chapter. The text needs to be selected before changing its display mode to ink, which is accomplished in the second line. If you do not first select the ink, you will not see a change in your control. It's worth noting that the InkEdit control does not try to convert text, which was entered into the control as text, into ink. Obviously, it would be impossible for the control to try to simulate what your handwriting should look like so that it could convert it into a mock form of writing.

We'll continue the process by adding the opposite code-displaying ink as text. We can begin by choosing 'btnDisplayAsText' from the class name listbox and then choose 'click' from the method name listbox. This creates the click event for the control for us. We need to add the following code to the event:

InkEdit1.SelectAll()
InkEdit1.SelInksDisplayMode = InkDisplayMode.Text

This code, like most in this section of the chapter, works similarly to the previous code. Again, it begins by selecting the text and then changes the display mode, but this time, it converts it to text.

Not only can we change the way ink is displayed, but we can also determine in what format the control actually collects ink. Remember that if you set this to insert the ink as text, it actually converts the ink to text, and, therefore, you cannot get the ink back. On the other hand, if you insert as ink, you can display it as ink or text and change it back and forth as many times as you want because there is no conversion actually taking place. Additionally, when the control tries to convert ink to text, it also tries to determine what type of word was entered and, therefore, may make changes you were not intending. These properties play a crucial role in the way the ink is utilized, so depending on the type of application you are trying to create, the correct property is extremely important.

To change the way the ink is inserted, you need a single line of code entered into the btnInsertAsInk and btnInsertAsText click events (refer back earlier in the chapter for information on creating the events):

Private Sub btnInsertAsInk_Click(ByVal sender As System.Object, ByVal e 
As System.EventArgs) Handles btnInsertAsInk.Click
 InkEdit1.InkInsertMode = InkInsertMode.InsertAsInk
End Sub

Private Sub btnInsertAsText_Click(ByVal sender As System.Object, ByVal e 
As System.EventArgs) Handles btnInsertAsText.Click
 InkEdit1.InkInsertMode = InkInsertMode.InsertAsText
End Sub

The final property we are going to work with at this time is the RecoTimeout property, which determines how long it takes for the control to begin the recognition process after your pen leaves the control. The property is set using milliseconds. You can create the btnSubRecoTime and btnIncreaseRecoTime events and enter the following code:

Private Sub btnSubRecoTime_Click(ByVal sender As System.Object, ByVal e 
As System.EventArgs) Handles btnSubRecoTime.Click
 If InkEdit1.RecoTimeout > 100 Then
 InkEdit1.RecoTimeout = InkEdit1.RecoTimeout - 100
 End If
End Sub

Private Sub btnIncreaseRecoTime_Click(ByVal sender As System.Object, ByVal e 
As System.EventArgs) Handles btnIncreaseRecoTime.Click
 If InkEdit1.RecoTimeout < 10000 Then
 InkEdit1.RecoTimeout = InkEdit1.RecoTimeout + 100
 End If
End Sub

The code uses a simple If...Then statement to determine how small the current timeout values are set. Its purpose is to limit how quickly the recognition occurs because a negative value would obviously cause problems. You can now save your project and run the application. You can try the various properties to see how they work. Figure 13.4 displays an example of what you will see as you set properties. For additional information, the default value for RecoTimeout is 2 seconds or 2000 milliseconds. Changing this value, like the earlier values, can play an important role in your applications. If you are writing some general purpose applications, 2 seconds is probably a good starting point. However, if you are writing something, such as a game, that recognizes what you are writing, you may need to shorten the value, or if you are creating an application for children, you may want to lengthen the time to allow for their generally slow handwriting speed.

click to expand
Figure 13.4: Setting various properties changes the way ink is displayed.

There are many other properties we could work with, but they are all covered extensively in the SDK. In addition, we also mention the specific properties we use during the creation of our many applications as we progress through the book.

Saving Content

After you have some content entered into the control, it is very easy to save it to disk and then reload it when needed. You simply need to call the SaveFile method and the LoadFile method to save to a file or to a stream. As an example, let's extend the application we have been working on to save the contents to 'C:myinktext.rtf.'

First, add buttons for loading and saving to the form with the properties shown in Table 13.2.

Table 13.2: Adding buttons for loading and saving to the form

Name

Text

btnSaveFile

Save File

btnLoadFile

LoadFile

The next step is to add a single line of code to the btnSaveFile and btnLoadFile click events. The line calls the SaveFile method and saves the file to C:MyInkTest.rtf. You will probably notice the RTF extension on the file that is given as the InkEdit control is based on the RichTextBox.

First, here is the code for the btnSaveFile event procedure:

InkEdit1.SaveFile("C:MyInkTest.rtf")

To load the file, you should call the LoadFile method. You can open the file with the following line of code to the btnLoadFile click event procedure:

InkEdit1.LoadFile("C:MyInkTest.rtf")

The sample you have now allows you to set various properties of the InkEdit control. You can also load and save files albeit in an extremely simple manner. There is one final thing that you can add to the program. To erase the text in InkEdit1 that is visible on startup, you can add the following line to the Form_Load event:

InkEdit1.Text = ""

That's it for this simple example. You can now save it and then create a new project as we now turn our attention to the InkPicture control.

Using the InkPicture Control

If you have not already done so, you need to create a new Windows Forms application and then add the InkPicture control to the form:

  1. Right-click on the Toolbox.
  2. Select Customize.
  3. Select the .NET Framework Components tab.
  4. Check InkPicture and then click OK.

You can now add an instance of the InkPicture control to your form as it is now visible in the Toolbox. You can select it and then draw a rectangle shape on your form. It will be positioned in the area in which you draw the rectangle.

The InkPicture control has some unique properties that we have the ability to manipulate. By default, the control captures ink and displays the ink so you don't have to do anything special with it. If you were to save and then run the current sample, you would see that the control does allow you to write with your pen (see Figure 13.5).

click to expand
Figure 13.5: The control displays ink by default.

You can close the running sample to return to the IDE, and we'll look at some of the properties provided by the InkPicture control.

Property Description

Like InkEdit, InkPicture also has its own set of properties. We'll look at the ActiveX properties, the Managed Library properties, and then a set of properties that are general to both.

ActiveX Only

The ActiveX control provides a set of properties that are specific to it.

hWnd: Returns the window handle to which the control is bound

MouseIcon: Returns or sets the current custom mouse icon

MousePointer: Returns or sets a value that indicates the type of mouse pointer that appears when the mouse is over a particular part of the control

tbpropicturePicture: Returns the graphics file to appear on the control

Managed Library Only

The Managed Library has a set of properties that are unique.

AccessibleDescription: Returns or sets the description of the control that the accessibility client applications use

AccessibleName: Returns or sets the name of the control that the accessibility client applications use

AccessibleRole: Returns or sets the role of the control that the accessibility client applications use

Anchor: Returns or sets which edges of the control are anchored to the edges of its container

BackgroundImage: Returns or sets the background image that appears in the control; allows you to add a picture that can be used for markup

BorderStyle: Returns or sets the border style for the control

ClipInkToMargin: Returns a value that specifies whether to clip strokes when they are outside the default margin

CollectingInk: Returns the value that specifies whether the control is collecting ink

ContextMenu: Returns or sets the shortcut menu to appear when the user right-clicks the control

DefaultMargin: Returns the default margin that the MarginX and MarginY properties use

Dock: Returns or sets to which edge of the parent container the control is docked

Handle: Gets the window handle to which the control is bound

Image: Returns or sets the image that appears in the control

Location: Returns or sets the coordinates of the upper-left corner of the control relative to the upper-left corner of its container

Size: Returns or sets the height and width of the control in pixels

General

The ActiveX and Managed Libraries both offer these properties.

AutoRedraw: Returns or sets a value that specifies whether the InkPicture repaints when the window is invalidated

BackColor: Returns or sets the background color for the control. The default background color is the system window background color, which is typically white

CollectionMode: Returns or sets the collection mode that determines whether ink, gestures, or ink and gestures are recognized as the user writes

Cursor: Returns or sets the cursor that appears when the mouse pointer is over the control

Cursors: Returns the number of cursors available for use in the ink-enabled region; each cursor corresponds to the tip of a pen or other ink input device

DefaultDrawingAttributes: Returns or sets the default drawing attributes to use when collecting and displaying ink

DesiredPacketDescription: Returns or sets the packet description of the control

DynamicRendering: Returns or sets the value that specifies whether the control dynamically renders the ink as it is collected

EditingMode: Returns or sets a value that specifies whether the control is in ink mode, deletion mode, or selecting/editing mode

Enabled: Returns or sets a value that determines whether the control can respond to user-generated events

EraserMode: Returns or sets the value that specifies whether ink is erased by stroke or by point

EraserWidth: Returns or sets the value that specifies the width of the eraser pen tip

  Note 

This property also appears in the InkOverlay object.

Ink: Returns or sets the Ink object that is associated with the InkPicture control

InkEnabled: Returns or sets a value that specifies whether the InkPicture control collects pen input

MarginX: Returns or sets the x-axis margin around the window rectangle in screen coordinates

MarginY: Returns or sets the y-axis margin around the window rectangle in screen coordinates

Selection: Returns or sets the collection of ink strokes that are currently selected

SizeMode: Returns or sets how the control handles image placement and sizing

SupportHighContrastInk: Returns a value that specifies whether ink is rendered as just one color when the system is in High Contrast mode

SupportHighContrastSelectionUI: Returns or sets a value that specifies whether all selection user interfaces are drawn in high contrast when the system is in High Contrast mode

Tablet: Returns the Tablet object that the InkPicture control is currently using to collect input; returns the object that represents the tablet hardware, such as manufacturer information

If you quickly browse the list, you will see some interesting properties and many will already look familiar to you because the InkEdit control shares many of the same properties.

As you remember, the InkPicture control is most often used to annotate images. With that in mind, it's important to learn about the properties that control ink selection and ink erasing. The first thing we'll deal with is removing (erasing) ink from the control. Your application can offer two erasing modes:

Point erase: Allows the user to erase a single pixel at a time

Stroke erase: Allows the user to erase the entire stroke, if the user touches anywhere on a stroke

Supporting erase functionality is imperative to many applications because it allows users to easily erase and reenter drawings that they have produced with ink. With the form you already have, add two buttons to the form with the properties shown in Table 13.3.

Table 13.3: Adding btnErasePoint and btnEraseStroke to the form

Name

Text

btnErasePoint

Erase Point

btnEraseStroke

Erase Stroke

Your form should now look like Figure 13.6.

click to expand
Figure 13.6: Your form now has buttons added for ink erasing.

It's now very quick and easy to add the erasing capability. Create the click events for both controls and then add the following code into the appropriate procedures:

Private Sub btnErasePoint_Click(ByVal sender As System.Object, ByVal e 
As System.EventArgs) Handles btnErasePoint.Click
 InkPicture1.EraserMode = InkOverlayEraserMode.PointErase
 InkPicture1.EditingMode = InkOverlayEditingMode.Delete
End Sub

Private Sub btnEraseStroke_Click(ByVal sender As System.Object, ByVal e 
As System.EventArgs) Handles btnEraseStroke.Click
 InkPicture1.EraserMode = InkOverlayEraserMode.StrokeErase
 InkPicture1.EditingMode = InkOverlayEditingMode.Delete
End Sub

The first line of code in each procedure sets the EraserMode property to Point or Ink respectively, whereas the second line of code sets the EditingMode property to Delete. These are the only two properties required for erasing. You should save the application and then test out the erasing. At this time, you can erase, but you don't have a way to begin drawing again. This can be handled with another button and a single line of code. Add the button shown in Table 13.4 to the form.

Table 13.4: Adding btnDraw to the form

Name

Test

btnDraw

Draw

Next, in the button's click event, you can add the following line of code, which again uses the EditingMode property, but now sets it to Ink:

InkPicture1.EditingMode = InkOverlayEditingMode.Ink

You can now move back and forth between the two different types of ink deletion and can also support drawing. Along these same lines, you might want to give the user the ability to select ink. Again, we can use the EditingMode property, but this time we can set it to Select. Add another button to the form called btnSelection and change its Text property to 'Selection.' Within the button's click event procedure, you can add the following line of code:

InkPicture1.EditingMode = InkOverlayEditingMode.Select

Your application now provides the ability to select ink, erase ink, and draw ink. We're now going to look at how we can alter the appearance of the ink collected in the control beginning with antialiasing. When you typically draw a line on a computer screen, its edges often have jagged edges. To antialias the controls so that they appear smooth, you use the Form_Load event and add the following line of code:

InkPicture1.DefaultDrawingAttributes.AntiAliased = True

Now, as you draw on the InkPicture control, the ink will be antialiased. There are certainly a number of additional properties, but these are some of the most important. In later chapters, we cover additional properties as we need them and you can refer to the SDK for additional information if needed.

Objects

Along with the controls we have been using in this chapter, the SDK also provides several objects that we can use throughout our applications.

InkCollector Object

The InkCollector object captures ink input that is placed into a known application window. The InkCollector object captures the input in real time and then directs it into an Ink object. The ink strokes can then be manipulated or sent to a recognizer for recognition.

InkOverlay Object

The next object to look at is the InkOverlay object, which is a superset of the InkCollector object and provides editing support. Both objects, as does the InkPicture control, use common constructs, such as the Ink object and the InkDrawingAttributes collection, so that the basic way to change the color of ink is the same everywhere. This enables you to reuse code and makes it much easier for you to remember. InkOverlay is perfect for annotation in which pen size, ink, color, and position are the most important aspects for a program.

InkOverlay differs from InkCollector in several ways:

  • It raises events for begin and end stroke, along with ink attribute changes.
  • It enables users to select, erase, and resize ink.
  • It supports Cut, Copy, and Paste commands.

The process for using InkOverlay and InkCollector are very similar. Let's create a sample application. First, open VB .NET and create a new Windows Forms application. Next, add a label control to the form and resize it so that it takes up much of the form's visible area. Open the Code Editor and then add references to the following:

Microsoft Tablet PC API

The next step is to add a button to the form and just leave it with its given name of Button1. You can also leave the standard Text property of 'Button1.' Now, back in the Code Editor, we can use the Form_Load event to programmatically set some of these properties and create the InkCollector:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 Label1.BackColor = Color.White
 Label1.Text = ""
 Button1.Text = "Recognize It"
 theInkCollector = New Microsoft.Ink.InkCollector(Label1.Handle)
 theInkCollector.Handle = Label1.Handle
 theInkCollector.Enabled = True
End Sub

The next step is to add the Button1_Click event, which we'll use to display a message box with the recognized text from our strokes. We'll use a simple Try and Catch to make sure we are executing this on a Tablet PC. This is good programming practice, but because we know that the applications we are developing in the majority of the examples are only going to run on a Tablet PC, we may skip this step.

Here is the code:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
 Dim strokes As Microsoft.Ink.Strokes = theInkCollector.Ink.Strokes

 Try
 MsgBox(strokes.ToString(), MsgBoxStyle.OKOnly, "VB.NET API")
 Catch
 MsgBox("Not a Tablet PC", MsgBoxStyle.OKOnly, "Error in VB.NET API")
 End Try
End Sub

The last thing we need to do is use the Dispose method of the InkCollector to prevent memory leaks. We can use the Form1_Closing event as a place to handle this:

Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
 theInkCollector.Dispose()
End Sub
Selecting Ink

You can now save and run the application. Enter some ink into the white area and then click the button that says 'Recognize It.' This should display the recognized text in a message similar to the one seen in Figure 13.7.

click to expand
Figure 13.7: Our application being tested.

Now, if you want to change the InkCollector to an InkOverlay, it's as simple as changing these two lines:

Dim WithEvents theInkCollector As Microsoft.Ink.InkCollector
theInkCollector = New Microsoft.Ink.InkCollector(Label1.Handle)

to read:

Dim WithEvents theInkCollector As Microsoft.Ink.InkOverlay
theInkCollector = New Microsoft.Ink.InkOverlay(Label1.Handle)

After changing the code, you can check the application to make sure everything works as expected. Now, let's expand upon the application. The InkOverlay object enables users to use a Lasso tool to select Ink objects or they can select ink by tapping any Ink object. It also allows us to erase ink. Like InkPicture, we also need to have a way to get back to Drawing mode. Now, let's add three additional buttons to the application, leaving them as named by default (i.e., Button2, Button3, Button4). We now go into the Form_Load event and add the following three lines of code:

Button2.Text = "Erase"
Button3.Text = "Draw"
Button4.Text = "Selection"

You're already familiar with the properties, so we can simply write the code for each of the events:

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As 
System.EventArgs) Handles Button2.Click
 theInkCollector.EraserMode = Microsoft.Ink.InkOverlayEraserMode.StrokeErase
 theInkCollector.EditingMode = Microsoft.Ink.InkOverlayEditingMode.Delete
End Sub

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As 
System.EventArgs) Handles Button3.Click
 theInkCollector.EditingMode = Microsoft.Ink.InkOverlayEditingMode.Ink
End Sub

Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As 
System.EventArgs) Handles Button4.Click
 theInkCollector.EditingMode = Microsoft.Ink.InkOverlayEditingMode.Select
End Sub

Adding Ink to Existing Applications

The final part of this chapter is devoted to adding ink to existing Windows Forms applications. You can certainly add controls such as InkPicture or InkEdit, or you can use objects such as InkOverlay, but the easiest way to add ink to an existing application is via the PenInputPanel object. As an attachable object, it allows you to add in-place pen input to your applications. You can choose either handwriting or keyboard options for the input method for the Pen Input Panel. Your end user will have the ability to switch between input methods using buttons on the user interface.

Let's create a simple example using the Pen Input Panel. Begin by creating a new Window Forms application in VB .NET. Next, add four standard TextBox controls to the window to simulate an existing VB application. Next, we need to add a reference to the Tablet PC API 1.5. Make sure to select the 1.5 API because version 1 does not include the PenInputPanel object.

The next step is to add the following Imports statement to the Code Editor:

Imports Microsoft.Ink

Add the following code to create the Pen Input Panel:

Dim thePenInputPanel As New PenInputPanel()

Now that we have created the Pen Input Panel, we need to attach it to a control before we can use it. We have two options for this. The first is to create three separate Pen Input Panels and then assign each of them to one of the text boxes. The other option is to create the single Pen Input Panel and then attach the control as necessary. In our case, we are going to attach the controls during the Mouse_Down events of the first three TextBox controls. We'll leave the last one alone so we can verify that the Pen Input Panel only works when we attach it to a control.

Here are the procedures and the code:

Private Sub TextBox1_MouseDown(ByVal sender As Object, ByVal e As 
System.Windows.Forms.MouseEventArgs) Handles TextBox1.MouseDown
 thePenInputPanel.AttachedEditControl = TextBox1
End Sub

Private Sub TextBox2_MouseDown(ByVal sender As Object, ByVal e As 
System.Windows.Forms.MouseEventArgs) Handles TextBox2.MouseDown
 thePenInputPanel.AttachedEditControl = TextBox2
End Sub

Private Sub TextBox3_MouseDown(ByVal sender As Object, ByVal e As 
System.Windows.Forms.MouseEventArgs) Handles TextBox3.MouseDown
 thePenInputPanel.AttachedEditControl = TextBox3
End Sub

You can now test the application. You should try to use your pen to click in the first three text boxes to verify that it works (see Figure 13.8). Additionally, try clicking in the fourth text box to verify that the Pen Input Panel does not appear. Lastly, if you have a mouse attached, try clicking in the text boxes with a mouse. This should verify that the Pen Input Panel does not work unless a pen is being used.

click to expand
Figure 13.8: The Pen Input Panel is displayed.

Summary

In this chapter, we were able to look at the InkEdit and InkPicture controls and also a few of the objects available to us, such as InkOverlay and InkCollector. They each offer various advantages and disadvantages depending on the type of application you are developing. You can use the InkEdit control for applications when text recognition is required, such as address text boxes, and use the InkPicture control for scenarios when you don't need text recognition, such as when you need to capture signatures. The objects are equally easy to use and share many of the same properties, making your decision on which way to develop a very easy decision. In Chapter 14, Tablet PC Full Screen Utility, we look at some of the hardware of the Tablet PC, including its special buttons and screen rotation.



Developing Tablet PC Applications
Developing Tablet PC Applications (Charles River Media Programming)
ISBN: 1584502525
EAN: 2147483647
Year: 2003
Pages: 191

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net