With the release of Windows 8, the era of touch devices is in full swing.  Manufacturers are scrambling to create mobile devices that can run Microsoft Windows with the touch of a finger, without the need for a keyboard and mouse.  Even Microsoft has released their very own Surface brand to satisfy this need to run Windows in a mobile world.  This is all fine and dandy if you are building Windows Store applications that run on any version of Windows 8, and are built with touch as a first class citizen.  Windows Store apps integrate perfectly with the device, such as automatically showing the Windows 8 touch keyboard when giving focus to an input element in the application.  Windows Store apps are smart enough to know when I am not using a mouse and keyboard, and I give focus to a TextBox by touching it, it will show the touch keyboard to allow me to input data.  On the other hand, if I am using a mouse and keyboard, and I give focus to the TextBox by clicking it with the mouse, the touch keyboard does not show, but rather I use the keyboard to enter my data.  This is a nice feature built into the platform.

Windows 8 touch keyboard

Although Microsoft has been shoving Windows Store apps down everyone’s throat, Windows Store apps are not a desktop solution, and in it’s current form, cannot replace certain desktop applications.  This means, that if you are a desktop developer and want your WPF applications to work in this new mobile world, you need to make your WPF apps more touch accessible.  Specifically, when dealing with running your WPF application on a Windows 8 Pro tablet, without the need for a mouse and keyboard.

Unfortunately, this is not as easy as we would like.  As you have probably discovered, there is no API in WPF to access the Windows 8 touch keyboard.  This means, that if a user loads your awesome WPF application onto their Surface Pro 2, and touches a input control, they have no way of entering data into that control.  Well, they can, but it won’t be obvious to them.  In order to enter any type of data into your WPF input controls, they would have to manually open the touch keyboard by tapping on the keyboard icon located in the taskbar.

image

Sure this works, but it is not the ideal experience.  Wouldn’t it be nice to have your WPF application behave just like a Windows Store app, and automatically show the touch keyboard when an input control gains focus by touch?  Well, you can, and I am going to show you how.  Just so you know, it doesn’t require calling Process.Start(“C:…TabTip.exe”).

The first thing we have to do is disable inking in the WPF application.  We do this because by default WPF touch support comes through the tablet platform’s real-time stylus input events (OnStylusDown, OnStylusUp, OnStylusMove).  Instead, we need to use the multi-touch input as Win32 WM_TOUCH windows messages.  This means we need to disable WPF listening to stylus input, and remove any tablet support added by the WPF Window.  This code is freely available and documented in the MSDN topic “Disable the RealTimeStylus for WPF Applications”.

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 });
                }
            }
        }
    }
}

The next thing we need to do is to get our WPF desktop application to opt-in to the focus tracking mechanism used in Windows Store applications.  We do this by implementing the IInputPanelComfiguration interface.  This will let our WPF app leverage the invoking and dismissing semantics of the touch keyboard and handwriting input panel.  Unfortunately, this is not a managed interface, and there is no DLL you can reference to use it.  There are two options for implementing this.

One, we can create an assembly from the IDL file located at c:Program Files (x86)Windows Kits8.1Includeuminputpanelconfiguration.idl:

    1. Start a command prompt
    2. Use the MIDL compiler tool to build a Type Library TLB file (learn more about MIDL Compiler see here on MSDN)
      1. Example: midl /tbld {filename}
    3. Use the TLBIMP tool to convert the above generated Type Library (TLB file) into a DLL that .NET can use by running the following command (learn more about Tlbimp.exe here on MSDN)
      1. Example: TLBIMP.exe InputpanelConfiguration.tlb /publickey:{pathToKey} /delaysign

This will create an unsigned DLL that you can now reference in your Visual Studio Solution.

Note:  TLBIMP.exe runs on .Net 4.0 and when we generate a DLL, the target version of the DLL is also targeted to .Net 4.0. So if you need to support .NET3.5, you can force TLBIMP to run on .Net 3.5 by adding the following change to the config file of TLBIMP.exe.  After this change, when we generate DLL using step 3, the DLL is targeted to .net 3.5.

<startup>
     <supportedRuntime version=”v2.0.50727″/>
</startup>

(Special thanks to Rob Relyea and Shiva Shankar of Microsoft for proving this note.)

Two, we can simply use a ComImport.  This is my preferred approach.

[Guid(“41C81592-514C-48BD-A22E-E6AF638521A6”)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IInputPanelConfiguration
{
    /// <summary>
    /// Enables a client process to opt-in to the focus tracking mechanism for Windows Store apps that controls the invoking and dismissing semantics of the touch keyboard.
    /// </summary>
    /// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns>
    int EnableFocusTracking();
}

[ComImport, Guid(“2853ADD3-F096-4C63-A78F-7FA3EA837FB7”)]
class InputPanelConfiguration
{
}

Now that we have taken care of the hard part, time to put the pieces together.  We first turn off inking by calling InkInputHelp.DisabeWPFTabletSupport, and then we call IInputPanelConfiguration.EnableFocusTracking.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Loaded += MainWindow_Loaded;

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

    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        //Windows 8 API to enable touch keyboard to monitor for focus tracking in this WPF application
        InputPanelConfiguration cp = new InputPanelConfiguration();
        IInputPanelConfiguration icp = cp as IInputPanelConfiguration;
        if (icp != null)
            icp.EnableFocusTracking();
    }
}

Now I can add a TextBox to my MainWindow.xaml, run the application, and watch the magic happen.

<Window x:Class=”WpfTouchKeyboard.MainWindow”
       xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
       xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
       Title=”MainWindow” Height=”350″ Width=”525″>
    <Grid>
        <TextBox AcceptsReturn=”True” />
    </Grid>
</Window>

Windows 8 touch keyboard shown from WPF application

When I touch the TextBox to give it focus, the touch keyboard will show allowing me to use it to enter data into the control.  If I click the TextBox with my mouse, the touch keyboard will not show, instead I have to use the keyboard to enter data into the control.  As you can probably guess, this is not an official support solution by Microsoft, so you can expect some behavioral differences compared to Windows Store apps.  For example, when you give touch focus to a control to show the touch keyboard, and then touch another area of your application, the keyboard may not hide as expected.  Basically, some controls will dismiss the touch keyboard (for example a Button), while others won’t.

I have been working with my friend Dmitry Lyalin to solve this issue.  He was vital to solving this, and he posted his own version of the solution to the Microsoft Developer Network.  You will notice some differences in his implementation than mine, but the end result is the same.  I would also like to note that Dmitry made a call to System.Windows.Automation.AutomationElement.FromHandle, but I do not see the need for the call, and do not notice any differences in behavior by not calling it.  If I discover otherwise, I will update this post.

Don’t forget to download the source code.

Feel free contact me on my blog, connect with me on Twitter (@brianlagunas), or leave a comment below for any questions or comments you may have.

Brian Lagunas

View all posts

57 comments

  • I’ve tried this method before after talking to the Windows team involved with the on screen keyboard. The downside to this method is that you have to disable WPF stylus support, and therefore the ability for native controls to react to stylus and touch. This can be an issue with controls such as the scrollviewer, etc that have built in panning for touches. This is a deal breaker for many.

    Another way to invoke the on screen keyboard is to have a singleton class that can invoke and dismiss the TabTip process using the Process api. You can have custom textbox that inherits from TextBox that calls the singleton class on TouchDown and LostFocus. You mentioned something close to this, I believe.

    BTW, you can use IFrameworkInputPane (http://msdn.microsoft.com/en-us/library/windows/desktop/hh706967(v=vs.85).aspx) and the associated handler so that UI elements can respond to the on screen keyboard if necessary when using the InputPanelConfiguration method.

    Let’s hope we can get proper touch support for desktop apps in the future.

  • In order to close the keyboard, it is possible to send close message (WM_SYSCOMMAND with SC_CLOSE) to the TabTip window on LostFocus event.

  • I am also in a situation where I have a desktop WPF app running on Windows 8 and face the Keyboard not showing when a text box is hit. What is the work around for now on calling the Windows 8 keyboard without having to disable stylus input in order to get other control to respond to touch ? any clear sample ?

    It is a pitty that Windows 8 has been think with only store in mind. We have many occasion and request to have for instance Desktop app in multiuser environement which request all this basic thing.

  • Thank you very much for your solution, but I use your solution there is a problem in my WPF desktop applications,
    is when my topmost WPF desktop applications on the metro, My WPF desktop application covered the keyboard ,
    can you solve this problem, it is best to give me the sample code, and my desktop application is not a Windows Store applications

  • thank you very much for your solution, but there is still a problem existed in my WPF desktop application which is when I run the application, the pop-up window will cover the touch- keyboard. Could you please help me to solve this problem? It is better to provide me the sample code so I can fix it effectively. By the way, my desktop application is not a Windows Store Application.
    In order to force your application above Metro’s User-Interface you’ll need to do the following:
    1. Create a Win32 Project
    2. Finish the wizard with no changes.
    3. Change the CreateWindowEXand set WS_EX_TOPMOST
    4. Go to Project.Properties and link to manifest file.
    5. Change UAC to bypass UI Protection; should be /uiAccess = “true”
    6. Build your project.
    7. Use the SignTool to sign the application.
    8. Ensure the application is stored in Program Files or Program Files (x86)
    9. Run your application.
    10. Load your Start Menu and your application should be running above Metro.

    • I’m sorry, but I do not understand your scenario. Based on your directions, you are not creating a WPF application, but rather a C++ Win32 application. This blog post was written specifically for .NET WPF desktop applications.

      I would like to add that since you are forcing the interface to be on top of Metro, it should be no surprise that your application is sitting above the touch keyboard. This would be the expected behavior, and should not be considered an “issue”. You specifically coded it that way.

  • WPF refers to the set of technologies (exposed via APIs) that .NET Framework 3.0 and above users have access to in order to draw to the screen.

  • I’m sorry,my english is poor,my wpf desktop application mainly to solve the two problems, first, suspended above the metro or desktop, and the second, when opening my wpf desktop application can display a touch keyboard and can not be blocked by my wpf desktop applications, such as in front of the other described.
    Thanks again
    Best Regards

    • I’m sorry, I do not understand your issue completely. Based on what I do understand, you have specifically enabled your application to show over metro applications. If you do not want this behavior, do not implement the steps you have listed.

  • Hi brian, I want to go home for the Chinese New Year, ask this question again a few days with you.
    Best Regards

  • Brian, thanks for this wonderful solution. I have a small problem, though: when the TextBox is defined inside the ControlTemplate of a ListBox, for instance, it doesn’t seem to work. Can you think of a workaround for this? Thanks

    • Hmm.. I’m not really sure about that. I have tested this solution with complex controls like the Infragistics xamDataGrid and it worked. That would take some investigating. I know the touch keyboard relies on UIAutomation, but the Textbox implements UIAutomation, so I’m really not sure what the problem could be. You might want to try calling System.Windows.Automation.AutomationElement.FromHandle to see if that helps at all.

    • Hi Luis. I ran into a similar problem. but in my case it was TabControl template who caused child TextBoxes not to trigger the on screen keyboard, though the original TabControl without a custom template worked fine. I compared the original template and my custom one, and found out that ContentPresenter in custom template lacked the “x:Name” attribute with “PART_…” assigned to it. With this attribute in place everything works fine. I didn’t investigate why this happens, though. Hope it helps.

  • I use this code and it is work, but it let the touch event not work, how can i support the table when i need to use the touch event?

  • Using this method can achieve a goal,but then there will be many problem,such as can’t use the MultiTouch Event.Have a better solotion?

  • Hi Brian. Thanks for the example. It worked for my WPF application. But I ran into a problem. I started the WPF application without the physical keyboard attached to my Surface Pro and the touch keyboard pops up fine. I then attached the physical keyboard to make sure that the touch keyboard didn’t pop up. I then removed the physical keyboard expectng the touch keyboard to pop up but it didn’t. The touch keyboard didn’t popup even after I restarted my WPF application. I had to log out and back in for it to start to pop up again. Have you seen or heard about this problem?

  • Dear,
    i can disable the wpf touch with your sample , but my application need on some control the touchmanipulation.
    How can reactivate the wpf touch?
    thanks

    • This approach disabled the built-in stylus touch support that you are used to. If using this, you must manually listen and handle the Win32 WM_TOUCH window messages.

  • Hi,thanks for your example,but my leader is insane,he wants the system keyboard can be positioned by wpf codes.
    Is there anyway to implement the stuation he wants??
    he will kill me if I can not do that.
    Thanks agian.
    Best Regards.

      • Perhaps a little off-topic, but if we were to use our own keyboard, is there a way to definitely ensure the native keyboard never shows? I found web content (input type texts) being focused in an embedded control “sometimes” invoked it.

        • Sorry for the late reply, I haven’t been getting notifications of new comments for some reason. I’m not sure if you can disable it all together. If you find out let me know.

  • Hello,
    I used 2nd solution,it works fine. Thanks for this. But guide me how to automatic disabled this keyboard popup.
    In windows8,wpf application I use this senario, but toch on combobox… It should be disable. Please give me suggestion.

    • Keep in mind that the code in this post is not supported, and was basically a hack to make it work. To my knowledge, there are no APIs available to have the type of control that you are looking for over the keyboard.

  • Brian –

    Thanks for the great article.

    You do a great job replying to questions in the comments as well … how kind of you. I got frustrated just reading those haha … so many people asking the same question and rudely demanding an answer.

    Well just thought you should have another friendly comment on this very helpful blog post to balance out the rest.

    I too need touch events and OSK … so here’s hoping the situation improves… luckily for me my ‘leader’ will not kill me over this 🙂

    • Thank you Travis, your comment is much appreciated. Luckily, the situation is much improved in Windows 10. The touch keyboard now respects the WPF input controls automatically. WIN!

  • Hi, great info, thank you. I am trying to capture wm_touch message in a WPF button. I was wondering if you knew of an example that does that.

    • A bit more info: I have the following triggers for a button template – from the other comments I expected them not to work anymore with a touchscreen and they don’t, but the Click event still fires when touching the button on a touchscreen. So I replaced with and this triggers. I’m assuming from other comments that I have to implement wm_touch for the buttons but I just want to make sure I actually have to. Thank you.

      • Sorry the code included disappeared, trying again – EventTrigger RoutedEvent=”PreviewMouseDown” does nit trigger but EventTrigger RoutedEvent=”Button.Click” does when touching the button

        • (Removed brackets)

          ControlTemplate.Triggers
          EventTrigger RoutedEvent=”PreviewMouseDown”
          BeginStoryboard Storyboard=”{StaticResource buttonDownStoryboard}”
          EventTrigger
          EventTrigger RoutedEvent=”PreviewMouseUp”
          BeginStoryboard Storyboard=”{StaticResource buttonUpStoryboard}”
          EventTrigger
          ControlTemplate.Triggers

  • Hi, it works great including in IE WebBrowser but for some reason not in the a Chrome version of WebBrowser called Awesomium. Would you have any idea why? Thank you.

  • Hi, i don’t know why but when i try to use your solution the program stay blocked inside this part :

    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});
    }

    There are three devices and no one could be removed.

    {System.Windows.Input.TabletDevice()}
    {System.Windows.Input.TabletDevice(??VIRTUAL_DIGITIZER)}
    {System.Windows.Input.TabletDevice(CoolTouch® USB Interface 1 )}

    May be i do something wrong. Have you any idea why ?

  • Hi Brain. Thanks for the article. Is there any option to show only numeric keypad? So could you please explain how i can achieve? Thanks in advance…!

  • Hi Brian,

    I integrated your solution on my app and, it just doesn’t run the application. If I do not call DisableWPFTabletSupport() than the application starts but of course it doesn’t solve the keyboard problem. I also ran the my app without your solution integrated and it runs.

    I used your sample app on the tablet and it has the same behavior: not running the app.

    I also checked the event log and I get two events worth mentioning:

    Application: NameOfMyApp.exe
    Framework Version: v4.0.30319
    Description: The process was terminated due to an unhandled exception.
    Exception Info: System.NullReferenceException

    and

    Faulting application name: NameOfMyApp.exe, version: xxxxxxxxx, time stamp: 0x558153c8
    Faulting module name: KERNELBASE.dll, version: 6.3.9600.17415, time stamp: 0x54504b59

    the specs of the tablet are:
    OS: Windows 8.1 , 32 bit
    Processor: Intel(R) Atom(TM) CPU Z2760 @ 1.80GHz
    RAM: 2 GB
    Pen and touch: Full Windows Touch Support with 5 Touch Points

    I also assured that I am targeting the correct platform from the configuration manager in VS (ANY CPU), since it is running 32 bit windows 8.
    I am really running out of ideas. Do you have any hints?

    Thnks!

    • Did you run the sample I provided to see if it runs? Also, keep in mind that the code in this post is not supported, and was basically a hack to make it work.

  • Hi Brian

    Great article.

    With the release of Windows 10 (and associated integration improvements between store apps and desktop apps) I just wondered whether there are any signs of an “official” solution for supporting the touch keyboard in WPF apps?

    Thanks,
    Andy

    • Not that I know of. I know UWP has been their main focus, so WPF has probably been an after thought. I am sure MS will do something to improve this story one day. I mean, they have to if they want Windows 10 to succeed and be adopted by the enterprise.

  • Is this post still relevant for .NET 4.6? I’ve tried implementing what you suggested but it raised some problems:
    1) the application is now much slower than without it
    2) scroll viewer is not scrolling
    3) on some occasions the textbox gets focused on touch but the keyboard will only pop up after a second touch

      • Thanks for your reply 🙂
        So this tutorial which was much more helpful than any other tutorial I found and helped me solve a lot of other touch related issues is still the way to go as far as you know?

        P.S.
        just started watching the Introduction to PRISM on PluralSight and it looks great.

Follow Me

Follow me on Twitter, subscribe to my YouTube channel, and watch me stream live on Twitch.