4
votes

Windows 10 has setting "Show the touch keyboard when not in tablet mode and there's no keyboard attached", which allows Windows to show touch keyboard whenever you touch text box.

As Windows handles this logic rather poorly (it is easily broken in WPF applications), I would like to turn off this option for my application, which I'm trying to do by changing registry value EnableDesktopModeAutoInvoke, corresponding to this option (simple Registry.SetValue method). But there is an issue - touch keyboard application TabTip.exe for some reason doesn't really "hook up" changes in registry, and keeps showing touch keyboard until it is restarted. And vice versa - once I'm restoring registry value, I need to restart application to apply change.

And this is where main issue of such approach appears - with auto-invoke option enabled, once TabTip process starts, it immediately shows keyboard. Obviously I would not like such visual side-effects for my application logic.

Another point is that while changing this setting in usual way, via Windows Settings application, TabTip or any related applications or services are not restarted. Which means Settings application somehow manages to update TabTip process. I would really like to figure how it does this, and if I can reproduce same behavior in C#, but I have no idea how.

So, my question is - how can I programmatically change either EnableDesktopModeAutoInvoke registry value or "Show the touch keyboard when not in tablet mode and there's no keyboard attached" Windows option, and make TabTip application to accept this change, without any possible visual side-effects?

UPD:

I know that it is possible to make keyboard to ignore text box by creating custom text box with specific automation peer, but this would require to replace all text boxes in entire application, and always keep in mind that we need to use new text boxes, so this is not viable solution. I've tried to remove possibility to get automation peers for children of main window as well, but that doesn't work.

3
Sadly, that doesn't work as well.lentinant
Most places I checked, everyone is killing the exe and doing it, and I don't have a windows system to check other workaroundsTarun Lalwani
Apparently we will go with this as well. This was my last resort, but apparently there is no other way at all.lentinant

3 Answers

0
votes

So I looked at lot of different implementations of the same

https://github.com/maximcus/WPFTabTip/blob/65b58e1900d3c21c9ea684e9f882088fe821586b/WPFTabTip/TabTip.cs

https://github.com/zhangtx2812/NewClient/blob/851f6dd8bc9c6389b70c7b5cd9384617a62a274e/Client.Helpers/Utils/KeyboardHelper.cs

https://github.com/Anneliese1989/Examintion/blob/2f974312d1ce0452a018bcaecf7bda753c818d9e/WPFTabTip/TabTip.cs

https://github.com/TransposonY/GestureSign/blob/11395ba6f18ea39b86f8e0a586b10a43f3c27568/GestureSign.CorePlugins/TouchKeyboard/TouchKeyboardUI.xaml.cs

https://github.com/microdee/mp.essentials/blob/d5832dee693839d55157d287d2459760b90b1d05/windows/WindowsLaunchOSKNode.cs

and most case one kills the process using

foreach (Process tabTipProcess in Process.GetProcessesByName(TabTipProcessName))
    tabTipProcess.Kill();

or close the keyboard using

void closeKeyboard()
{
    uint WM_SYSCOMMAND = 274;
    uint SC_CLOSE = 61536;
    IntPtr KeyboardWnd = FindWindow("IPTip_Main_Window", null);
    PostMessage(KeyboardWnd.ToInt32(), WM_SYSCOMMAND, (int)SC_CLOSE, 0);
}

So, I think what you have already are the best choices known

0
votes

I have a shot in the dark for you...

Here's one way that it is possible TabTip is notified of registry changes by Windows Settings but not by you: If TabTip is using something like the WMI RegistryKeyChangeEvent class internally, it's possible that the TabTip application is only monitoring the parent registry key and not monitoring the key value you're actually changing (which is why TapTip not updated when you change the value). But, the Windows Settings application could be setting the whole key (and it's corresponding valueName and value) via something like SetExpandedStringValue, which would trigger the key change that TabTip could be watching.

The way to test for this would be to set the key, valueName, and value all at once programmatically, instead of just setting the value.

0
votes

Not a great solution, but you could attempt to hook up to the showing event https://docs.microsoft.com/en-us/uwp/api/windows.ui.viewmanagement.inputpane

And immediately call a TryHide in the event of a show event to suppress it.