Как использовать Windows на экранной клавиатуре в C# WinForms

  • VS 2010
  • разработка 32-разрядного приложения, которое работает на 64-разрядной ОС (Win7, Win8 - desktop app)
  • C#
  • .NET 4.0
  • приложения WinForms

я нашел много потоков при запуске экранной клавиатуры Windows (osk.exe) из приложения, но я сталкиваюсь с некоторыми проблемами. Похоже, это потому, что я запускаю 32-разрядное приложение на 64-разрядной ОС. Я пробовал код, отправленный WooCaSh здесь: клавиатура на экране Приложения WinForms

но ни один из трех различных путей для меня. Для "sysnative" путь, процесс.Старт "не удается найти указанный путь.- Для систем32 и ОСК.exe-пути, я получаю диалоговое окно ошибки" не удалось запустить экранную клавиатуру".

я нашел здесь возможный обходной путь, который немного сложнее, чем то, что я искал (сообщение от eryang): http://social.msdn.microsoft.com/Forums/en-US/netfx64bit/thread/10ebc62f-e6d7-4072-9fd1-ea3784a0966f/

  1. есть ли более простой или правильный способ сделать это?
  2. Я надеялся, что запуск моего приложения на планшете автоматически запустит экранную клавиатуру, когда пользователь выберет текстовое поле, но не повезло. Это нормально или я что-то пропустила? редактировать: обнаружено, что клавиатура не запускается автоматически в Win8, когда на рабочем столе режим (который является моим приложением): http://www.bleepingcomputer.com/forums/t/480250/keyboard-does-not-pop-up-automatically/ по-видимому, он работает на планшетах Win7, но я не могу проверить, потому что у меня есть только Win8 таблетки здесь.

5 ответов


теперь я запускаю "сенсорную клавиатуру" в отличие от " экранной клавиатуры "(которая является клавиатурой, которую я хотел в Windows 8 в любом случае) с:

string progFiles = @"C:\Program Files\Common Files\Microsoft Shared\ink";
string keyboardPath = Path.Combine(progFiles, "TabTip.exe");

this.keyboardProc = Process.Start(keyboardPath);

это работает на моих Win7 и Win8, независимо от моего 32-разрядного приложения на 64-разрядной ОС. Тем не менее, у меня все еще есть проблема программного закрытия клавиатуры, когда я закончу. Процесс, это.keyboardProc, похоже, не получает дескриптор и сразу имеет свойство HasExited = true. Это означает мои попытки закрыть или убить его. неудача.

в соответствии с этим потоком, если пользователь вручную открывает клавиатуру (или я программно запускаю ее), клавиатура не будет автоматически закрываться/скрываться, когда текстовое поле теряет фокус: Windows 8 - Как уволить сенсорную клавиатуру? я попробовал обходной путь установки фокуса на скрытую кнопку, но так как я сам запустил клавиатуру, она не закрывается автоматически.


у меня возникли проблемы с закрытием экранной клавиатуры. Вы можете запустить сенсорную клавиатуру с помощью

        string progFiles = @"C:\Program Files\Common Files\Microsoft Shared\ink";
        string onScreenKeyboardPath = System.IO.Path.Combine(progFiles, "TabTip.exe");
        onScreenKeyboardProc = System.Diagnostics.Process.Start(onScreenKeyboardPath);

и закройте все клавиатуры с

            //Kill all on screen keyboards
            Process[] oskProcessArray = Process.GetProcessesByName("TabTip");
            foreach (Process onscreenProcess in oskProcessArray)
            {
                onscreenProcess.Kill();
            }

по какой-то причине onScreenKeyboardProc.Убить или. Close () не работает.


для автоматического открытия клавиатуры элементы управления должны реализовать некоторые шаблоны управления UI Automation, в частности ITextProvider / IValueProvider. Это неприятность, но она работает (и это более чистый способ, чем запуск некоторых *.exe)

Я написал пример приложения и короткую статью здесь: http://blog.tombam.net/implementing-textbox-with-on-screen-touch-keyboard-part-1/


сенсорная клавиатура использует автоматизацию пользовательского интерфейса. По некоторым причинам, которые для меня загадка, стандартное окно редактирования Windows не реализует UI automatic, в то время как другие элементы управления, такие как поле со списком, делают.


можно использовать реализацию автоматизации пользовательского интерфейса из UIAutomationClient.dll.

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

можно добиться что, например, вызывая кажущийся no-op:

AutomationElement.FromHandle(IntPtr)(-1)

другой способ-явно реализовать интерфейс автоматизации. Для реализации ITextProvider/IValueProvider интерфейсы для соответствующего входного контроля.

чтобы привязать реализацию интерфейсов к элементу управления, handle WM_GETOBJECT окне С lParam = RootObjectId.

для примера реализации, см.

хотя интересно, что элементы управления, для которых сенсорная клавиатура работает из коробки (например, поле со списком или поле редактирования пароля, см. ответ), не реализуют WM_GETOBJECT/RootObjectId. Должно быть, за ними стоит другая машина.


наиболее распространенные "решение" этой проблемы, чтобы явно всплывающее окно клавиатуры, запустив TabTip.exe или osk.exe, вряд ли приемлема.

если ни для чего другого, то потому, что нет чистого способа скрыть клавиатуру, открытую при запуске TabTip.exe (решения включают хаки, такие как убийство процесса или отправка Esc key).

и на самом деле вышеупомянутый Хак, похоже, больше не работает в Windows 10 Anniversary Update: показать сенсорную клавиатуру (TabTip.exe) в Windows 10 Anniversary edition.


Начиная TabTip.exe больше не работает в издании Widnows 10 Anniversary. Я обнаружил недокументированный COM-интерфейс для управления сенсорной клавиатурой. Проверьте код здесь https://stackoverflow.com/a/40921638/332528