更改EnableDesktopModeAutoInvoke注册表值并使TabTip.exe接受更改

时间:2018-05-14 15:34:51

标签: c# windows registry on-screen-keyboard

Windows 10的设置为“不在平板电脑模式下显示触摸键盘,并且没有连接键盘”,这使Windows可以在您触摸文本框时显示触摸键盘。

由于Windows处理此逻辑的效果相当差(在WPF应用程序中很容易被破坏),我想为我的应用程序关闭此选项,我试图通过更改注册表值EnableDesktopModeAutoInvoke来执行此操作到这个选项(简单的Registry.SetValue方法)。但是有一个问题 - 触摸键盘应用程序TabTip.exe由于某种原因并没有真正“挂钩”注册表中的更改,并一直显示触摸键盘,直到它重新启动。反之亦然 - 一旦我恢复注册表值,我需要重新启动应用程序以应用更改。

这就是出现这种方法的主要问题 - 启用自动调用选项,一旦TabTip进程启动,它会立即显示键盘。显然,我不喜欢这种视觉副作用对我的应用程序逻辑。

另一点是,以通常方式更改此设置时,通过Windows设置应用程序,TabTip或任何相关的应用程序或服务不会重新启动。这意味着设置应用程序以某种方式设法更新TabTip进程。我真的想知道它是如何做到的,如果我可以在C#中重现相同的行为,但我不知道如何。

所以,我的问题是 - 如何以编程方式更改EnableDesktopModeAutoInvoke注册表值或“在平板电脑模式下显示触摸键盘并且没有连接键盘”Windows选项,并使TabTip应用程序接受此更改,没有任何可能的视觉副作用?

UPD:

我知道可以通过创建具有特定自动化同行的自定义文本框来使键盘忽略文本框,但这需要替换整个应用程序中的所有文本框,并始终牢记我们需要使用新的文本框,所以这不是可行的解决方案。我试图消除为主窗口的孩子获得自动化同伴的可能性,但这不起作用。

3 个答案:

答案 0 :(得分:0)

我在黑暗中为你射击......

这是一种可能的方式,TabTip可以通过Windows设置通知注册表更改,但不是您:如果TabTip在内部使用类似WMI RegistryKeyChangeEvent类的内容,则TabTip应用程序可能只监视父注册表项,而不是监视您实际更改的键值(这就是更改值时TapTip未更新的原因)。但是,Windows设置应用程序可能会通过类似SetExpandedStringValue的内容设置整个key(以及相应的valueNamevalue),这会触发TabTip可能会发生的关键更改正在看。

测试此方法的方法是以编程方式一次性设置keyvalueNamevalue,而不是仅设置value

答案 1 :(得分:0)

所以我看了很多相同的

的不同实现

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

大多数情况下使用

杀死进程
foreach (Process tabTipProcess in Process.GetProcessesByName(TabTipProcessName))
    tabTipProcess.Kill();

或使用

关闭键盘
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);
}

所以,我认为你已经拥有的是最好的选择

答案 2 :(得分:0)

不是一个很好的解决方案,但您可以尝试连接到显示事件https://docs.microsoft.com/en-us/uwp/api/windows.ui.viewmanagement.inputpane

如果出现show事件,立即调用TryHide来抑制它。

相关问题