When I run a WinForms (or Delphi, see at the end) application on Windows 10 in a tablet mode, a touch keyboard does not pop up automatically, when an input box is focused.
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 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);
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
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.
Use a RichTextBox instead of a TextBox control. The RichTextBox supports the touch keyboard and will automatically pop up the keyboard when focus is gained. (similar to other input controls such as the combo box)
The RichTextBox also supports the same properties as the TextBox so it should be a drop in change in most cases. (Both controls derive from TextBoxBase)
I have noticed that if the touch keyboard has been dismissed after it pops up, you may have to tap twice on the control to get it to pop back up.