Automatically pop up tablet touch keyboard on WinForms input focus
I've been down this road a few times and have only ever been able to implement the taptip.exe
option. And in turn close the window by killing the process. I also found out that with some registry hacks you can get the keyboard to default to the handwriting panel if you so choose. But then that only works in Win8 and fails in Win10. Here is what I've done in case anyone else finds this useful:
RegistryKey registryKey = Registry.CurrentUser.CreateSubKey("Software\\Microsoft\\TabletTip\\1.7");
registryKey?.SetValue("KeyboardLayoutPreference", 0, RegistryValueKind.DWord);
registryKey?.SetValue("LastUsedModalityWasHandwriting", 1, RegistryValueKind.DWord);
Process.Start(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");
I need to give credit to this post for the registry idea: Windows 8 Desktop App: Open tabtip.exe to secondary keyboard (for numeric textbox)
As hinted by Ofek Shilon's answer, it seems that the touch keyboard can leverage the UI automation.
One can use implementation of UI automation from UIAutomationClient.dll
.
For the UI automation to be magically injected into an application, class initializer of the assembly internal class UiaCoreApi
have to be triggered.
On can achieve that for example by calling seeming no-op:
AutomationElement.FromHandle(IntPtr)(-1)
Another way is to implement automation UI explicitly. For that implement the ITextProvider
/IValueProvider
interfaces for the respective input control.
To bind the implementation of the interfaces to the control, handle WM_GETOBJECT
window message with lParam
= RootObjectId
.
For an example of implementation, see
- tombam's answer to How to use Windows On-Screen Keyboard in C# WinForms
- or directly poster's article Implementing TextBox with on-screen touch keyboard.
Though interestingly, controls, for which touch keyboard works out-of-the-box (like combo box or password edit box, see the answer), do not implement the WM_GETOBJECT
/RootObjectId
. There must be a different machinery behind them.
As far as I can tell, launching osk.exe
or tabtip.exe
pretty much is the "standard" way of making this work. I've found no "official" solution so far.
However, if it were me doing this, I wouldn't be killing the process or sending keys to try and dismiss the keyboard. Instead, you can obtain the window handle when you launch the process, and use that to minimize the window and hide it from the taskbar.
Someone here has gotten the window handle just to close it, but it gives you the idea: Show & hiding the Windows 8 on screen keyboard from WPF
If you need me to, let me know and I'll see if I can find the time to do up a full example.
The root cause seems to be that Winforms' textBox is not an AutomationElement, while the rest of the mentioned controls (ComboBoxes etc) are.
Quoting Markus von und zu Heber's accepted answer here:
We found it in the article "Automatic Touch Keyboard for TextBoxes in WPF Applications on Windows 8+", but it also works very good (and even easier!) for winforms. Thank you, Dmitry Lyalin!
Insert a reference to UIAutomationClient.dll to your project
In the form-load-handler of the application's main window, insert the following code:
var asForm = System.Windows.Automation.AutomationElement.FromHandle(this.Handle);