FujitsuStylistic.com

The InkEdit Control


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:
Create a new project.
Right-click on the Toolbox.
Select Customize.
Select the .NET Framework Components tab.
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.



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.
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.
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.