Ink in WPF -- Using TextInputPanel for Text Input

Posted Wednesday, October 01, 2008 12:08 PM by Nathan Zaugg

Ink-Logo WPF has built-in controls for ink, but is missing much of the API that is available in the TabletPC SDK 1.7.  As a result, unless you are doing the most basic and mundane ink you will be required to use this library.  One of those basic things that are missing is the ability to open the TextInputPanel in an WPF application. 

The TextInputPanel is a tool that ships with certain versions of Vista (in previous versions of windows it was called a Pen Input Panel) that enables handwriting recognition and an on-screen keyboard.  It makes text input into a text box easy when the user is operating with a Tablet PC.  The problem is that the .NET assembly only supports hwnd-based controls and WPF controls (thankfully) are not hwnd-based. 

So while trying to figure this out, and off the clock from the project I was on, I made a class that helped bridge the gap between WPF and the TextInputPanel.

TextInputPanel

Before you try to use this you will need to do two things.

First you need to download and install the TabletPC SDK 1.7 (if you haven't already) and download my class (Source / Binary)

Second you need to start the Tablet PC Input Panel if you on a regular PC.  To do this go to:

Start -> All Programs -> Accessories -> Tablet PC -> Tablet PC Input Panel

To use the class as a binary application, simply add the DLL as a reference.  Once that is done you will need to create an instance of the class for each text box you wish to have ink input (shown below).  IMPORTANT: THIS SHOULD BE DONE ON THE WINDOW LOAD EVENT! IF YOU PUT THIS CODE IN THE CONSTRUCTOR IT WILL NOT WORK!

<?xml version="1.0" encoding="utf-8"?>
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        x:Class="TestApp" 
        Title="Ink Input App" 
        Loaded="Window_Loaded">
    <Grid>
        <TextBox Name="tbTest" Height="30" Width="300" /> 
    </Grid>

 

protected InkInputPanel pnltbTestInk;

...

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    // Enable the Ink Input Panel
    pnltbTestInk= new InkInputPanel(tbTest, true);
}

The code above will display the TextInputPanel anytime the textbox has focus and will go away when it looses focus.  This is the simplest way to use the class.  If you are doing something more complex like making the input panel appear when a button is clicked you will have some slightly different code.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    // Enable the Ink Input Panel
    pnltbTestInk = new InkInputPanel(tbTest, false); // False for AutoShow
}
private void InputFieldButton_Click(object sender, RoutedEventArgs e) {
    tbTest.Focus();
    pnltbTestInk.Show();
}

protected void tbTest_LostFocus(object sender, RoutedEventArgs e) {
    pnltbTestInk.Hide();
}

Just make sure that you focus the text box before you call show on the Text Input Panel.

Basically the class I created uses the COM object exposed by the SDK rather than the Microsoft.Ink.dll assembly.  The COM object is called "Microsoft PenInputPanel 1.7" and is found at C:\Program Files\Common Files\Microsoft Shared\ink\tiptsf.dll

If you are able to make use of my class or have questions or feedback, please leave a comment!

UPDATE

I received a number of emails indicating that using this code for multiple text boxes didn't work (it threw a COM exception).  I have modified the code to fix this issue and have uploaded it.  Because of a COM limitation, there is a change in how you use the API.  The biggest change is that you only need one instance of the class and you can attach multiple text boxes to this one instance.

Example:

protected InkInputPanel pnltbTest;

...

private void Window_Loaded(object sender, RoutedEventArgs e) {
    pnltbTest = new InkInputPanel(tbTest, true);
    pnltbTest.AddAttachedTextBox(tbTest1, true);
    pnltbTest.AddAttachedTextBox(tbTest2, true);
    pnltbTest.AddAttachedTextBox(tbTest3, true);
}

if you are going to hide and show the panel explictly, then you will need to use one of the indexers available on the InkInputPanel class.

Example:

protected InkInputPanel pnltbTestInk;

...

private void Window_Loaded(object sender, RoutedEventArgs e) {
    // Enable the Ink Input Panel
    // Pass false for AutoShow
    pnltbTestInk = new InkInputPanel(tbTest, false); 
}

private void InputFieldButton_Click(object sender, RoutedEventArgs e) {
    tbTest.Focus();
    pnltbTestInk[tbTest].Show();
}

protected void tbTest_LostFocus(object sender, RoutedEventArgs e) {
    pnltbTestInk[tbTest].Hide();
}
Links

 

Comments

# re: Ink in WPF -- Using TextInputPanel for Text Input

Monday, November 17, 2008 11:58 PM by Eric

Hi,

Thanks first of all for taking the time and writing up a nice way to use the text input panel control in WPF.

One question though, how about multiple textboxes in one form? I get COMExceptions whenever I try to attach more than one TextInputPanel.

# re: Ink in WPF -- Using TextInputPanel for Text Input

Tuesday, November 18, 2008 1:35 AM by Nathan Zaugg

I have updated the code and the API slightly to fix a bug the code had.  Re-download the code and try again.  Let me know if you have any other problems!

Also, if you find it useful, feel free to submit this page to Digg (just added it and never tried that before).

Thanks!

Nathan Zaugg

# re: Ink in WPF -- Using TextInputPanel for Text Input

Tuesday, November 18, 2008 1:37 AM by Nathan Zaugg

I also working on a post for a custom control called InkedTextBox that does all of this automatically.  

# re: Ink in WPF -- Using TextInputPanel for Text Input

Thursday, November 20, 2008 12:40 AM by Eric

Hey it's me again, just wanted to come back and say it works like a charm! So thanks for all the effort and keep up the good work.

-Eric

# re: Ink in WPF -- Using TextInputPanel for Text Input

Saturday, April 25, 2009 10:10 AM by fuzb

Windows 7 does pop up the TIP tooltip in WPF textboxes automatically.

(but not password boxes yet it seems, which is why I ended up here!)

# Incorporating the Windows 7 onscreen keyboard into a WPF app |Windows 7 Application | Windows 7 Guide

Pingback from  Incorporating the Windows 7 onscreen keyboard into a WPF app |Windows 7 Application | Windows 7 Guide

# rimonabantexcellence site title

Wednesday, June 05, 2013 5:54 PM by rimonabantexcellence site title

Pingback from  rimonabantexcellence site title