Измените значение реестра EnableDesktopModeAutoInvoke и заставьте TabTip.exe принять изменения - PullRequest
0 голосов
/ 14 мая 2018

В Windows 10 есть настройка «Показывать сенсорную клавиатуру, когда она не находится в режиме планшета, и клавиатура не подключена», что позволяет Windows отображать сенсорную клавиатуру при каждом касании текстового поля.

Поскольку Windows обрабатывает эту логику довольно плохо (она легко нарушается в приложениях WPF), я хотел бы отключить эту опцию для своего приложения, что я пытаюсь сделать, изменив значение реестра EnableDesktopModeAutoInvoke, соответствующее этому опция (простой Registry.SetValue метод). Но есть проблема - приложение с сенсорной клавиатурой TabTip.exe по какой-то причине не «подцепляет» изменения в реестре и продолжает показывать сенсорную клавиатуру до ее перезапуска. И наоборот - после восстановления значения реестра мне нужно перезапустить приложение, чтобы применить изменения.

И именно здесь возникает основная проблема такого подхода - при включенной опции автозапуска после запуска процесса TabTip сразу отображается клавиатура. Очевидно, я не хотел бы таких визуальных побочных эффектов для логики моего приложения.

Другой момент заключается в том, что при изменении этого параметра обычным способом через приложение «Настройки Windows» вкладка «Tab» или любые другие связанные приложения или службы не перезапускаются. Это означает, что приложению Настройки каким-то образом удается обновить процесс TabTip. Мне бы очень хотелось понять, как это происходит, и могу ли я воспроизвести такое же поведение в C #, но я понятия не имею, как это сделать.

Итак, мой вопрос - как я могу программно изменить либо значение реестра EnableDesktopModeAutoInvoke, либо параметр «Показывать сенсорную клавиатуру, когда не в режиме планшета, и клавиатура не подключена», и заставить приложение TabTip принимать это изменение без любые возможные визуальные побочные эффекты?

UPD:

Я знаю, что можно заставить клавиатуру игнорировать текстовое поле, создав пользовательское текстовое поле с определенным одноранговым узлом автоматизации, но для этого потребуется заменить все текстовые поля во всем приложении, и всегда помнить, что нам нужно использовать новые текстовые поля, так что это не жизнеспособное решение. Я попытался удалить возможность получения пиров автоматизации для детей основного окна, но это не работает.

Ответы [ 3 ]

0 голосов
/ 21 мая 2018

Итак, я посмотрел на множество разных реализаций одного и того же

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

Итак, я думаюто, что у вас уже есть, является лучшим выбором из известных

0 голосов
/ 07 июня 2018

Не очень хорошее решение, но вы можете попытаться подключиться к отображающему событию https://docs.microsoft.com/en-us/uwp/api/windows.ui.viewmanagement.inputpane

И немедленно вызвать TryHide в случае события показа, чтобы подавить его.

0 голосов
/ 17 мая 2018

У меня для вас есть шанс ...

Вот один из способов, которым возможно, что TabTip уведомляется об изменениях реестра с помощью параметров Windows, но не вами: если TabTip использует что-то вроде WMI RegistryKeyChangeEvent внутри класса, возможно, что приложение TabTip отслеживает только родительский раздел реестра и не отслеживает значение ключа, которое вы фактически изменяете (поэтому TapTip не обновляется при изменении значения).Но приложение настроек Windows может устанавливать целые значения key (и соответствующие им valueName и value) через что-то вроде SetExpandedStringValue , что приведет к смене ключа, который может наблюдать TabTip.

Чтобы проверить это, можно задать программные настройки key, valueName и value одновременно, а не просто value.

...