How to use Windows On-Screen Keyboard in C# WinForms
Asked Answered
B

6

18
  • VS 2010
  • Developing 32-bit app that runs on 64-bit OS (Windows 7, Windows 8 - desktop app)
  • C#
  • .NET 4.0
  • WinForms

I have found many threads on launching the Windows on-screen keyboard (osk.exe) from an application, but I am running into some problems. It appears to be because I am running a 32-bit app on a 64-bit OS. I've tried the code posted by WooCaSh here: Keyboard on the screen in WinForms

But none of the three different paths work for me. For the sysnative path, Process.Start fails with "Cannot find the path specified." For the system32 and osk.exe paths, I get the "Could not start the on-screen keyboard" error dialog.

I found a possible workaround here, which is a little more complicated than what I was looking for (post by eryang): http://social.msdn.microsoft.com/Forums/en-US/netfx64bit/thread/10ebc62f-e6d7-4072-9fd1-ea3784a0966f/

  1. Is there an easier or correct way to do this?
  2. I was hoping that running my app on a tablet would automatically launch the on-screen keyboard when the user selects a textbox, but no luck. Is this normal or am I missing something? I've found that the keyboard is not automatically launched in Windows 8 when in Desktop mode (which my app is): http://www.bleepingcomputer.com/forums/t/480250/keyboard-does-not-pop-up-automatically/ Apparently it works on Windows 7 tablets, but I can't test because I only have Windows 8 tablets here.
Bellwether answered 21/3, 2013 at 17:58 Comment(4)
Just change the Platform target setting on your EXE project to "AnyCPU".Symons
Unfortunately it needs to be x86 for some 3rd party software it interacts with.Bellwether
Just for testing, I went ahead and changed to "AnyCPU". The keyboard still would not launch on my Win7 64-bit desktop, but launches on the Win8 64-bit tablet. Any ideas?Bellwether
I've implemented the approach described [here][1]. It works on Win7, too. [1]: https://mcmap.net/q/393767/-wpf-windows-8-tabtip-closeLyman
B
23

I am now launching the "Touch Keyboard" as opposed to the "On-Screen Keyboard" (which is the keyboard I wanted on Windows 8 anyway) with:

string progFiles = @"C:\Program Files\Common Files\Microsoft Shared\ink";
string keyboardPath = Path.Combine(progFiles, "TabTip.exe");

this.keyboardProc = Process.Start(keyboardPath);

This works on my Win7 and Win8, regardless of my 32-bit app on 64-bit OS. However, I still have the problem of programmatically closing the keyboard when I'm done. The process, this.keyboardProc, does not seem to get the handle, and immediately has property HasExited = true. This means my attempts to close or kill it fail.

According to this thread, if the user manually opens the keyboard (or I programmatically launch it), the keyboard will not automatically close/hide when the text field loses focus: Windows 8 - How to Dismiss Touch Keyboard? I tried the workaround of setting the focus to a hidden button, but since I launched the keyboard myself, it doesn't close automatically.

Bellwether answered 22/3, 2013 at 17:56 Comment(4)
Great job! I've wasted at least an hour on this crap. Your solution helped me out.Winnick
Worked for me on Windows 10 tablet as well. Nothing like keeping a dinosaur alive...Polygamy
Please note that you might not have the "Tablet PC Components" windows features installed... if not goto the Control Panel, Programs and Turn Windows Features off or onDisjunctive
It seems that this may now be required on Windows10 for this to work in Desktop Mode: Registry.SetValue("HKEY_CURRENT_USER\Software\Microsoft\TabletTip\1.7", "EnableDesktopModeAutoInvoke", 1);Domain
E
12

I had trouble closing the on screen keyboard. You can start the Touch Keyboard with

string progFiles = @"C:\Program Files\Common Files\Microsoft Shared\ink";
string onScreenKeyboardPath = System.IO.Path.Combine(progFiles, "TabTip.exe");
onScreenKeyboardProc = System.Diagnostics.Process.Start(onScreenKeyboardPath);

and close all keyboards with

//Kill all on screen keyboards
Process[] oskProcessArray = Process.GetProcessesByName("TabTip");
foreach (Process onscreenProcess in oskProcessArray)
{
    onscreenProcess.Kill();
}

For some reason onScreenKeyboardProc.Kill() or .Close() doesn't work.

Esophagitis answered 31/7, 2013 at 9:9 Comment(0)
B
7

For the keyboard to open up automatically, the controls have to implement some UI Automation control patterns, specifically ITextProvider/IValueProvider. It is a nuisance, but it works (and it is a cleaner way than launching some *.exe)

I wrote a sample app and a short article here: http://blog.tombam.net/implementing-textbox-with-on-screen-touch-keyboard-part-1/

Ballyrag answered 10/5, 2017 at 7:27 Comment(1)
Fantastic article! Have you discovered a way to force a numeric keyboard?Seleta
S
2

The touch keyboard leverages the UI automation. For some reasons that are a mystery to me, the standard Windows edit box does not implement UI automation, while other controls, like combo box, do.


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.


The most common "solution" to this problem, to explicitly popup the keyboard by running the TabTip.exe or osk.exe, is hardly acceptable.

If for nothing else, then because there's no clean way to hide the keyboard opened by running the TabTip.exe (solutions include hacks like killing the process or sending Esc key).

And actually the above hack does not seem to work anymore in Windows 10 Anniversary Update: Show touch keyboard (TabTip.exe) in Windows 10 Anniversary edition.

Serial answered 25/5, 2017 at 6:50 Comment(0)
B
0

Starting TabTip.exe no longer works in Widnows 10 Anniversary Edition. I discovered an undocumented COM interface for controlling the touch keyboard. Check the code here https://mcmap.net/q/391082/-show-touch-keyboard-tabtip-exe-in-windows-10-anniversary-edition

Bellay answered 1/12, 2016 at 22:45 Comment(0)
S
0

I've surfing here and somewhere else then I implement this:

using System.Diagnostics; // remember use this

public partial class Window1 : Window
{

    public Process _p = null;
   
    public Window1()
    {
        InitializeComponent();          
    }

    public void Button_Click(object sender, RoutedEventArgs e)
    {
        if (_p != null)
        {
            _p.Kill();
            _p.Dispose();
            _p = null;
        }
        _p = Process.Start(@"C:\Program Files\Common Files\microsoft shared\ink\TabTip.exe");    
    }

    private void Acceso_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        if (_p != null)
        {
            _p.Kill();
            _p.Dispose();
            _p = null;
        }
    }
}

It works properly, so I share it here in case it helps as your info helped me.

St answered 18/8, 2020 at 13:46 Comment(1)
Thanks for include the missing lines, you are right the info already present here and other web was helpfull to me, I just collected them in a way that works properly for my case and I hope it can help someone else. thaks for the feedback.Nealey

© 2022 - 2024 — McMap. All rights reserved.