1
votes

I have a tablet which has to run an application with numeric input fields. However, I'm having trouble getting the windows keyboard (TabTip.exe) to pop up showing the numeric keypad by default.

The keypad needs to pop up automatically when the text field is clicked on.

I managed to get it to display the keyboard on each field by running TabTip.exe in the TextBox event handler, but it displays the normal keyboard layout. This was using an answer to this question: Show & hiding the Windows 8 on screen keyboard from WPF

    protected override void OnStartup(StartupEventArgs eventArgs)
    {

        // Popup keyboard, Select All on getting focus.
        EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotFocusEvent,
                                new RoutedEventHandler(GotFocus_Event), true);
        EventManager.RegisterClassHandler(typeof(TextBox), UIElement.LostFocusEvent,
                                new RoutedEventHandler(LostFocus_Event), true);

    }

    private static void GotFocus_Event(object sender, RoutedEventArgs e)
    {
        // The popup keyboard.
        OpenTouchKeyboard(sender, e);
    }

    private static void OpenTouchKeyboard(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";
            Process.Start(path);
            textBox.BringIntoView();
        }
    }

I read in the following page that you can use the text box's "InputScope" property to dictate that it should be a numeric keypad.

https://msdn.microsoft.com/nl-nl/library/windows/apps/xaml/mt280229?f=255&MSPPError=-2147217396#touch_keyboard_index_for_windows_and_windows_phone

So something like <TextBox Header="Name" InputScope="Number"/>

However, this has no effect, it still pops up with the regular layout. Also, I find it hard to believe that the InputScope would just pass itself down to the execution of the TabTip.exe process, without some way of linking them up.

I've also come across this: Start TabTip with numpad view open which suggests editing the registry before each call to TabTip.exe, but this seems very messy and is apparently unreliable in Windows 10.

Isn't there a command line argument or something that can be passed to it?

1

1 Answers

1
votes

I have found answer to this, with thanks to MSDN which pointed me to Automatic Touch Keyboard.

So basically I had been going it the wrong way

The correct way to do it: Add references to InputPanelConfigurationLib.dll and UIAutomationClient.dll

Then disable the Ink Input thusly...

using System; 
using System.Reflection; 
using System.Windows.Input; 

namespace ModernWPF.Win8TouchKeyboard.Desktop 
{ 
    public static class InkInputHelper 
    { 
        public static void DisableWPFTabletSupport() 
        { 
            // Get a collection of the tablet devices for this window.   
            TabletDeviceCollection devices = System.Windows.Input.Tablet.TabletDevices; 

            if (devices.Count > 0) 
            { 
                // Get the Type of InputManager. 
                Type inputManagerType = typeof(System.Windows.Input.InputManager); 

                // Call the StylusLogic method on the InputManager.Current instance. 
                object stylusLogic = inputManagerType.InvokeMember("StylusLogic", 
                            BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic, 
                            null, InputManager.Current, null); 

                if (stylusLogic != null) 
                { 
                    //  Get the type of the stylusLogic returned from the call to StylusLogic. 
                    Type stylusLogicType = stylusLogic.GetType(); 

                    // Loop until there are no more devices to remove. 
                    while (devices.Count > 0) 
                    { 
                        // Remove the first tablet device in the devices collection. 
                        stylusLogicType.InvokeMember("OnTabletRemoved", 
                                BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic, 
                                null, stylusLogic, new object[] { (uint)0 }); 
                    } 
                } 
            } 
        } 
    } 
} 

And in MainWindow.xaml.cs...

public MainWindow() 
{ 
    InitializeComponent(); 

    // Disables inking in the WPF application and enables us to track touch events to properly trigger the touch keyboard 
    InkInputHelper.DisableWPFTabletSupport(); 

    this.Loaded += MainWindow_Loaded; 
} 

private void MainWindow_Loaded(object sender, RoutedEventArgs e) 
{ 

    System.Windows.Automation.AutomationElement asForm = 
        System.Windows.Automation.AutomationElement.FromHandle(new WindowInteropHelper(this).Handle); 


    InputPanelConfigurationLib.InputPanelConfiguration inputPanelConfig = new InputPanelConfigurationLib.InputPanelConfiguration(); 
    inputPanelConfig.EnableFocusTracking(); 
} 

And lo and behold, selecting a text box calls up the Keyboard. However, now, it pays attention to the InputScope, which, if I set to Number causes the numeric keypad to be displayed.