Подтвердить что ты не робот

Как использовать экранную клавиатуру Windows в С# WinForms

  • VS 2010
  • Разработка 32-разрядного приложения, работающего на 64-разрядной ОС (Windows 7, Windows 8 - приложение для настольных компьютеров)
  • С#
  • .NET 4.0
  • WinForms

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

Но ни один из трех разных путей не работает для меня. Для sysnative пути Process.Start завершается с ошибкой "Не удается найти указанный путь". Для путей system32 и osk.exe я получаю диалоговое окно с сообщением об ошибке "Не удалось запустить экранную клавиатуру".

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

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

Ответ 1

Сейчас я запускаю "Сенсорную клавиатуру", а не "Экранную клавиатуру" (это клавиатура, которую я хотел в 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-битной ОС. Тем не менее, у меня все еще есть проблема программного закрытия клавиатуры, когда я закончу. Процесс this.keyboardProc, похоже, не получает дескриптор и сразу же имеет свойство HasExited = true. Это означает, что мои попытки закрыть или убить его не удаются.

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

Ответ 2

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

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.Kill() или.Close() не работает.

Ответ 3

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

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

Ответ 4

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


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

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

Это можно сделать, например, с помощью вызова no-op:

AutomationElement.FromHandle(IntPtr)(-1)

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

Для привязки реализации интерфейсов к WM_GETOBJECT управления обработайте сообщение окна WM_GETOBJECT с помощью lParam= RootObjectId.

Пример реализации см.

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


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

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

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

Ответ 5

Запуск TabTip.exe больше не работает в Widnows 10 Anniversary Edition. Я обнаружил недокументированный COM-интерфейс для управления сенсорной клавиатурой. Проверьте код здесь fooobar.com/info/166376/...