13

I'm writing a WPF application for a Windows 8 tablet. It's full windows 8 and not ARM/RT.

When the user enters a textbox I show the on screen keyboard using the following code:

System.Diagnostics.Process.Start(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");

This works fine however I don't know how to hide the keyboard again?

Anybody know how to do this?

Also, is there any way I can resize my application so that focused control is moved up when the keyboard appears? A bit like it does for a windows RT application.

Many Thanks

Sun
  • 4,458
  • 14
  • 66
  • 108

8 Answers8

19

I could successfully close onscreen keyboard with the following C# code.

[DllImport("user32.dll")]
public static extern int FindWindow(string lpClassName,string lpWindowName);

[DllImport("user32.dll")]
public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);

public const int WM_SYSCOMMAND = 0x0112;
public const int SC_CLOSE = 0xF060;

private void closeOnscreenKeyboard()
{
    // retrieve the handler of the window  
    int iHandle = FindWindow("IPTIP_Main_Window", "");
    if (iHandle > 0)
    {
        // close the window using API        
        SendMessage(iHandle, WM_SYSCOMMAND, SC_CLOSE, 0);
    }  
}

private void Some_Event_Happened(object sender, EventArgs e)
{
    // It's time to close the onscreen keyboard.
    closeOnscreenKeyboard();
}

I hope this will help you.

tasasaki
  • 695
  • 5
  • 12
6

A little bit late, I'll just improve tasaki example for a complete one of what I did to enable show/hide on gotFocus/LostFocus event when user click on a textBox in my WPF application for windows 8 tablet.I hope this help people with similar headache, because disabling InkHelper, doesn't really work well if u want to scroll with touch event...

First of all u must add these reference to your App.Xaml.cs File.

using System.Management;
using System.Runtime.InteropServices;

The code:

    protected override void OnStartup(StartupEventArgs eventArgs)
    {
        EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotFocusEvent,
                                new RoutedEventHandler(GotFocus_Event), true);
        EventManager.RegisterClassHandler(typeof(TextBox), UIElement.LostFocusEvent,
                                new RoutedEventHandler(LostFocus_Event), true);

       MainApplication.Show();
    }

    private static void GotFocus_Event(object sender, RoutedEventArgs e)
    {
       // TestKeyboard();
        OpenWindows8TouchKeyboard(sender, e);
    }
    //http://www.c-sharpcorner.com/UploadFile/29d7e0/get-the-key-board-details-of-your-system-in-windows-form/
    private static bool IsSurfaceKeyboardAttached()
    {
        SelectQuery Sq = new SelectQuery("Win32_Keyboard");
        ManagementObjectSearcher objOSDetails = new ManagementObjectSearcher(Sq);
        ManagementObjectCollection osDetailsCollection = objOSDetails.Get();
        //Windows 8 tablet are returnign 2 device when keyboard is connecto
        //My application won't be used for Desktop so this condition is fine
        //But u might want to see if keyboard is usb and == 1 so you are 
        //returning true or not on tablet.  
        return osDetailsCollection.Count <= 1 ? true : false;
    }

    private static void OpenWindows8TouchKeyboard(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;        
        if (textBox != null && IsSurfaceKeyboardAttached())
        {
            var path = @"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe";
            if (!File.Exists(path))
            {
                // older windows versions
                path = Environment.GetFolderPath(Environment.SpecialFolder.System) + @"\osk.exe";
            }
            Process.Start(path);
            textBox.BringIntoView();//SetFocus so u dont lose focused area
        }
    }
    [DllImport("user32.dll")]
    public static extern int FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll")]
    public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);

    public const int WM_SYSCOMMAND = 0x0112;
    public const int SC_CLOSE = 0xF060;
    public const int SC_MINIMIZE = 0xF020;

    private void CloseOnscreenKeyboard()
    {
        // retrieve the handler of the window  
        int iHandle = FindWindow("IPTIP_Main_Window", "");
        if (iHandle > 0)
        {
            // close the window using API        
            SendMessage(iHandle, WM_SYSCOMMAND, SC_CLOSE, 0);
        }
    }

    private void LostFocus_Event(object sender, EventArgs e)
    {
        // It's time to close the onscreen keyboard.
        CloseOnscreenKeyboard();
    }
torvin
  • 6,515
  • 1
  • 37
  • 52
Guillaume
  • 180
  • 1
  • 8
3

I open-sourced my project to automate everything concerning TabTip integration in WPF app.

You can get it on nuget, and after that all you need is a simple config in your apps startup logic:

TabTipAutomation.BindTo<TextBox>();

You can bind TabTip automation logic to any UIElement. Virtual Keyboard will open when any such element will get focus, and it will close when element will lose focus. Not only that, but TabTipAutomation will move UIElement (or Window) into view, so that TabTip will not block focused element.

For more info refer to the project site.

Max
  • 310
  • 3
  • 7
0

Well I would try something like this

Process myProcess = Process.Start(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");
myProcess.CloseMainWindow();
myProcess.Close();
Kapitán Mlíko
  • 4,498
  • 3
  • 43
  • 60
  • Thanks for the reply any ideas about moving the screen up when the keyboard appears – Sun Jun 14 '13 at 06:50
  • @user1131657 well that's harsh... don't you want to do that easier way? There should be some... For example have a look at [WPF Touch Screen Keyboard](https://wpfkb.codeplex.com/)... there will be more... and it looks like better solution than what yopu are trying to do. – Kapitán Mlíko Jun 14 '13 at 09:50
  • Viktor, I've been playing with this a little more and would prefer to use the built in touch screen keyboard. Why re-invent the wheel right! I've tried your code but it doesn't work. When the CloseMainWindow line run I receive the following error: Process has exited, so the requested information is not available – Sun Jun 14 '13 at 14:01
  • Well... Then I will be of no help for you. Sorry. last thing I found is this [question](http://stackoverflow.com/q/1168203/1456174) it's tagged win7, but it could help you. GL ;) – Kapitán Mlíko Jun 14 '13 at 14:19
  • This doesn't work. Tabtip has special behaviour where Windows will recycle a master instance to TabTip that it launches itself. So the instance you launch is transient and immediately goes away. Windows will instead show any existing instance or launch a new instance as required. The answer from @tasasaki works perfectly. – donovan Jun 19 '14 at 07:43
0

I am not sure how to hide the keyboard programmatically, but just as you know I just recently published a sample on how to trigger (as-in, show) the touch keyboard in WPF applications when a user clicks into a Textbox, its here:

http://code.msdn.microsoft.com/Enabling-Windows-8-Touch-7fb4e6de

The cool thing about this sample, as it doesn't require the use of Process and instead uses supported Windows 8 API to trigger the touch keyboard for TextBox controls using automation.

It has been something I've been working on for many months, i'm glad to finally contribute this example to our community. Please let me know if there are any questions, suggestions, problems, etc in the sample Q&A pane

Dmitry Lyalin
  • 444
  • 5
  • 8
0

try this one

System.Diagnostics.Process.Start("TabTip.exe");

I hope this will help you.

Amirhossein Yari
  • 2,054
  • 3
  • 26
  • 38
0

Maybe you can try the solution published on this blog: http://mheironimus.blogspot.nl/2015/05/adding-touch-keyboard-support-to-wpf.html

It contains some of the things you asked for (and more):

  • Show and hide keyboard
  • Move focus using FrameworkElement.BringIntoView ()
  • FrameworkElement.InputScope property to choose which keyboard layout to show (numeric, email, url, etc)
pogosama
  • 1,818
  • 1
  • 24
  • 29
-1

This should work to open, then kill the process.

Process proc = Process.Start(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");
proc.Kill();

Killing the process will close it.

If you debug and step through these two lines, however, the same error you mentioned above occurs - "Process has exited, so the request information is not available."

If you aren't stepping through these two lines while debugging, no exception is thrown and the on-screen keyboard will be killed.

If you use CloseMainWindow() the keyboard will not close. CloseMainWindow() is for processes with a UI, so you would think it would be effective on this, but perhaps because the keyboard is part of the OS it doesn't count.

Confirm that it works, then throw the proc.Kill() in a try-catch with error logging for peace of mind.

Community
  • 1
  • 1
jporcenaluk
  • 966
  • 10
  • 25