How to make the Windows OSK open when a TextBox gets focus, instead of requiring users to tap a keyboard icon?

2

We are working on a WPF application in .NET 4 that will be used with a touch screen. We are trying to use the built-in Windows OSK for our input, and the last remaining issue is to get the keyboard to open up as soon as a text box gets focus. Currently, if a text box gets focus, a small keyboard icon appears (this is the InputPanel icon) and the user has to tap that icon to make the keyboard open up.

Is there a way to skip the icon step, and just have the keyboard open up all the way on focus? Preferably something that can be set or coded in one place and apply to all text boxes globally? It also needs to use the current culture settings of the application thread (which it already appears to be doing).

I haven't been able to find anything in the control panel settings that lets you skip the icon step. I also found some examples online of using the TextInputPanel.CurrentInPlaceState, but when I implemented code to open up a TextInputPanel on preview focus of the main window, I kept getting COM INTEROP exceptions and basically hit a dead end (the Microsoft.Ink.dll is an interop DLL).

Is it possible that there is a registry key that can change the default CurrentInPlaceState to Expanded instead of HoverTarget? I haven't been able to find one in my net searching.

Thanks,

Valerie

EDIT: Here is some code that I put in the main window's code behind, as well as the exception message I keep getting - and I have no idea what it means or how to fix it (my net searches failed me!)

protected override void OnPreviewGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
    {
        base.OnPreviewGotKeyboardFocus(e);

        TextBox textbox = e.NewFocus as TextBox;
        TextBox oldTextbox = e.OldFocus as TextBox;

        if (oldTextbox != null && boxesToInputs.ContainsKey(oldTextbox))
        {
            TextInputPanel oldPanel = boxesToInputs[oldTextbox];
            oldPanel.Dispose();
            boxesToInputs.Remove(oldTextbox);
        }

        if (textbox != null)
        {
            // Make sure we've cleaned up old panels, just in case
            if (boxesToInputs.ContainsKey(textbox))
            {
                boxesToInputs[textbox].Dispose();
                boxesToInputs.Remove(textbox);
            }

            TextInputPanel newPanel = new TextInputPanel(((HwndSource)PresentationSource.FromDependencyObject(textbox)).Handle);
            newPanel.DefaultInPlaceState = InPlaceState.Expanded;
            newPanel.DefaultInputArea = PanelInputArea.Keyboard;
            boxesToInputs[textbox] = newPanel;
        }
    }

And here is the exception message, which occurs when my code calls the TextInputPanel constructor:

Retrieving the COM class factory for component with CLSID {F9B189D7-228B-4F2B-8650-B97F59E02C8C} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))

I verified that the platform target of the WPF app is x86. I ran Dependency Walker and it said that the Microsoft.Ink.dll I was using was 64 bit, and that two delay-loaded dependencies were missing (GPSVC.dll and IESHIMS.dll). I found a 32 bit version of Microsoft.Ink.dll, but I am still getting the same error, and Dependency Walker is saying the same thing - GPSVC.dll and IESHIMS.dll are missing.

I can't target x64, and I'd prefer not to have to put the missing DLLs into my application folder (if that would work?). I hope there is something simple I am missing, because this is a lot of trouble to just get rid of a keyboard hint...

Any help is greatly appreciated - I am a bit of a newb when it comes to working with unmanaged/interop assemblies...

wpf
textinput
touchscreen
on-screen-keyboard
asked on Stack Overflow Sep 22, 2011 by Valerie • edited Sep 22, 2011 by H.B.

1 Answer

1

I researched for a similar propose. In my case it was to create a custom OSK. It seems that (by now) it's not possible to create a custom input device. The explanation is in this link: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/a813a08a-7960-45fe-bc91-e81cdb75bd10

Moreover, I found a "workaround" which uses Win32 API calls to access SendKey method, and report input independently of the target. The project that I found is: http://wosk.codeplex.com/

SendKey is also available on WinForms (see http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx ) but I'm not sure if it will produce the same behavior.

I'll checking these options in the following days, but perhaps some of this information might help.

Regards Herber

answered on Stack Overflow Sep 23, 2011 by hmadrigal

User contributions licensed under CC BY-SA 3.0