How can I make the touch keyboard appear automatically when focus enters an edit control in my program?


By default, the Windows 8 touch keyboard does not appear automatically when focus is placed on an edit control in a desktop program. To change the behavior for your program, just use this one weird trick:

HRESULT EnableTouchKeyboardFocusTracking()
{
  ComPtr<IInputPanelConfiguration> configuration;
  HRESULT hr =
    CoCreateInstance(__uuidof(InputPanelConfiguration), nullptr,
      CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&configuration));
  if (SUCCEEDED(hr)) {
    hr = configuration->EnableFocusTracking();
  }
  return hr;
}

You create an instance of the Input­Panel­Configuration object and ask it to enable focus tracking. This is a per-process setting, and once set, it cannot be unset.

Let's use this function in a Little Program so you can play with it. Most of the work in setting up the program is creating two controls: an edit control and a button. If I had just one control, then you wouldn't be able to see how the keyboard automatically appears and disappears when focus moves between an edit control and some other type of control.

Remember that Little Programs do little to no error checking. Start with the scratch program and make these changes:

#define STRICT
#include ...
#include <shobjidl.h>
#include <inputpanelconfiguration.h>
#include <wrl\client.h>
#include <wrl\event.h>

using namespace Microsoft::WRL;

HINSTANCE g_hinst;                          /* This application's HINSTANCE */
HWND g_hwndChild;                           /* Optional child window */
HWND g_hwndButton;
HWND g_hwndLastFocus;

void
DoLayout(HWND hwnd, int cx, int cy)
{
  if (g_hwndChild) {
    MoveWindow(g_hwndChild, 0, 0, cx - 100, cy, TRUE);
  }
  if (g_hwndButton) {
    MoveWindow(g_hwndButton, cx - 100, 0, 100, 50, TRUE);
  }
}

void
OnSize(HWND hwnd, UINT state, int cx, int cy)
{
  DoLayout(hwnd, cx, cy);
}

BOOL
OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
{
  g_hwndChild = CreateWindow(TEXT("edit"), nullptr,
    WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE,
    0, 0, 100, 100, hwnd, nullptr, g_hinst, 0);
  g_hwndButton = CreateWindow(TEXT("button"), TEXT("Send"),
    WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
    0, 0, 100, 100, hwnd, nullptr, g_hinst, 0);

  EnableTouchKeyboardFocusTracking();
  return TRUE;
}

// OnActivate incorporated by reference.

 HANDLE_MSG(hwnd, WM_ACTIVATE, OnActivate);

BOOL
InitApp(void)
{
  ...
  wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
  ...
}

We position the edit control on the left hand side of the window and put the button in the upper right corner. We enable focus tracking on the touch keyboard, and just to make it easier to see where the edit control is, we give the frame with the app-workspace color.

Although we summon the touch keyboard when focus enters the edit control, we do nothing to prevent the keyboard from covering what the user is typing. This is one of the reasons that the touch keyboard does not appear automatically when focus is placed in an edit control of a desktop program. It would end up covering the edit control the user is trying to type into!

We'll work on fixing this problem next week.

Comments (13)
  1. skSdnW says:

    There is one very annoying problem with the automatic touch keyboard, it seems to have some sort of connection to the old on screen keyboard.

    Start osk.exe and minimize it, now try using the touch keyboard in a metro app!

    Is there any way to disconnect the OSK from the touch keyboard?

  2. anonymouscommenter says:

    > This is a per-process setting, and once set, it cannot be unset.

    I can already see it. A third-party dynamically loaded DLL (shell extension, printer driver) enables that setting in its own dialog boxes, and doesn't turn it off. The host program cannot defend itself against it.

  3. anonymouscommenter says:

    "By default, the Windows 8 touch keyboard does not appear automatically when focus is placed on an edit control in a desktop program. To change the behavior for your program, just use this one weird trick."

    Weirdest Buzzfeed headline ever.

  4. Entegy says:

    Looking forward to next week's solutions then. I know you can "anchor" the touch keyboard, but that seems to work by reducing the desktop space to work with, squishing the app, and some apps don't take well to that.

  5. Dan Bugglin says:

    The touch keyboard does indeed appear when you focus edit controls in SOME desktop applications if it happens as the result of a touch action. Even if a hardware keyboard is connected.

    I think this is only happening for Office applications (Lync/Outlook I tested quickly just now). I am not sure if it is the result of your code (you mention it should happen as a result of a focus, so even the mouse or hardware keyboard focusing does it I assume… which is not the case in Office).

    Anyway the OS likes to move the window out of the way of the keyboard when it appears. In addition you can set the keyboard to dock to the bottom of the screen so windows CAN'T go under it (which means all your windows are now resized and squished). I imagine your fix is going to invoke one of these if only because it's standard (and there's no better way to go about it, really).

    [This API (plus the ones to be introduced over the next few weeks) is how Office does its touch keyboard magic. In other words: I'm teaching you how to do magic. -Raymond]
  6. anonymouscommenter says:

    Typically settings that can be set but not unset are security features, like memory protection mechanisms. That way you can set them at program startup and malicious code cannot remove them.

    In this case, though, I suspect that nobody thought that DisableFocusTracking() would be needed and thus there is no way to unset EnableFocusTracking().

  7. Dave Bacher says:

    If you are implementing this in your app, please keep in mind…

    It is often the single most annoying thing you can do to a user of a touch device.

    When I am filling out a web form, and I touch a field to set focus — it does not follow that I'm intending to use the touch keyboard to type.  When you reflow the document twice every time I touch an input field, that gets real annoying, real fast.  Unfortunately, Microsoft does not yet capture swear words spoken near the computer as part of the customer improvement program.

  8. anonymouscommenter says:

    @Dave Bacher:  Hear, hear!  You are EXACTLY right.

  9. anonymouscommenter says:

    @Dave Bacher, yeah, I'm usually found poking the touch screen in front of me, brutally stretching one of my arms from the keyboard and back, too!  I guess that makes two of us!  Wow, why didn't Microsoft thought of us all?

  10. anonymouscommenter says:

    I have a Windows 8 tablet (a real tablet form factor, with no built-in or detachable keyboard), and without the touch keyboard automatically appearing when I set focus, the tablet would be unusable. I'm hoping that more applications implement this behavior.

  11. anonymouscommenter says:

    I suppose the "right thing to do" depends on a combination of whether your device HAS a keyboard, and what you are thinking when you touch the screen.  

  12. anonymouscommenter says:

    I think in this case the "right thing to do" is probably "whatever the user has indicated their preferred operation is via a setting".

    And people who tap the screen while reading are probably a sub-set of text selection readers.  Come to think of it I do both as well.

  13. anonymouscommenter says:

    "By default, the Windows 8 touch keyboard does not appear automatically when focus is placed on an edit control in a desktop program. To change the behavior for your program, just use this one weird trick"

    MSDN staffers hate him!

Comments are closed.

Skip to main content