- PVSM.RU - https://www.pvsm.ru -

После получения задачи использования в своём проекте экранной клавиатуры для сенсорного устройства я начал искать способы её реализации. Из возможных вариантов под Windows мне повстречались такие решения:
Встроенная клавиатура TabTip, osk.exe - не имеют возможностей гибкой кастомизации, появляются по произвольным координатам экрана и имеют только определенный размер.
Бесплатные решения - у таких подходов страдала реализация и компоненты выглядели даже похуже встроенной Windows клавиатуры.
Платные аналоги - действительно являются хорошей альтернативой со множеством необходимых настроек, но не было никакой бюджетной возможности покупать профессиональные решения.
В итоге своя клавиатура была создана с нуля — полностью на GDI+.
Эта статья - переработанная и дополненная версия моего материала, опубликованного в 2017 году на CodeProject.
Архив оригинала [1].
В проекте реализовано два пользовательских элемента: самостоятельно отрисованная клавиатура-эмулятор и текстовое поле с этой всплывающей клавиатурой.
Приложенный пользовательский WinForms компонент может быть настроен под нужды интерфейса вашего приложения и позволяет манипулировать внешним видом/дизайном и поведением.
VirtualKeyboard - пользовательский WinForms-контрол создан, в основном с помощью программироваания GDI+. Этому элементу управления присуще следующие свойства:
FirstRowCustomButtons … FifthRowCustomButtons - списки клавиш соответствующего ряда.
признак состояния клавиш клавиатуры: Shift, CapsLock, Alt ... (ShiftState, AltState …).
возможность скрыть/показать функциональные кнопки: Delete, Tab, Ctrl, кнопки со стрелками, цифровые кнопки (ShowDel, ShowTab … ).
визуальные настройки (цвет фона, шрифты).
показывать или нет только цифровой вариант (IsNumeric).
Каждая клавиша клавиатуры представлена классом-объектом VirtualKbButtonс отдельными свойствами:
верхний и нижний текст (TopText/BottomText).
шрифты для верхней и нижней части (TopFont/BottomFont).
признак, может ли кнопка отправлять команду (CanSendCommand).
тег и имя (Tag, ButtonName).
изображение (Picture).
По умолчанию создаётся стандартная английская раскладка, но её можно полностью заменить. Код для создания раскладки по-умолчанию расположен в классе KeyboardLayout.
Пользователь клавиатуры может работать или с отдельной кнопкой, либо с рядом, содержащим список Listклавиш.
Пример добавления кнопки:
var btn = new VirtualKbButton();
btn.TopText = "www";
btn.Tag = "btn_Internet";
virtualKeyboard1.FifthRowCustomButtons.Add(btn);
Пример удаления клавиши:
buttons.Remove(buttons[buttons.Count - 1]);
Пример создания своего второго ряда клавиш:
var row = new ButtonsCollection
{
new VirtualKbButton("A", ""), new VirtualKbButton("B", ""),
new VirtualKbButton("C", ""), new VirtualKbButton("D", ""),
new VirtualKbButton("E", ""), new VirtualKbButton("F", "")
};
virtualKeyboard1.SecondRowCustomButtons = row;
Можно подгружать раскладки из внешних источников, например XML.
Пользователь может сам обрабатывать нажатие кнопки клавиатуры через событие ButtonClick. Например:
private void virtualKeyboard_KeyboardButtonPressed(string command, KeyboardButtonEventArgs e)
{
switch (command)
{
case "a":
Debug.WriteLine("Нажат символ 'a'");
break;
case "Backspace":
Debug.WriteLine("Нажат 'Back space'");
break;
default:
Debug.WriteLine($"Клавиша '{command}'");
break;
}
}
Тексты команд, которые посылают специальные кнопки (Tab, Enter, Backspace…) находятся в классе KeyboardKeyConstants.
За счёт этого клавиатура легко адаптируется под любые задачи.
С помощью метода SendKeys.Send каждая кнопка может симулировать нажатие клавиши.
Поддерживаются:
обычные символы:
SendKeys.Send("a"); //Нажат символ 'a'
SendKeys.Send("~"); // Нажат символ '~'
спецсимволы, которые нужно обернуть фигурными скобками:
SendKeys.Send("{%}"); // Нажат символ '%'
SendKeys.Send("{+}"); // Нажат символ '+'
специальные клавиши (ENTER, ESC)
SendKeys.Send("{ENTER}");
SendKeys.Send("{ESC}");
комбинации( "+" для Shift, "^" для Ctrl, "%" для Alt):
SendKeys.Send("^c"); // Ctrl + C
SendKeys.Send("^%s"); // Ctrl + Alt + S
SendKeys.Send("%{F4}"); // Alt + F4
Когда пользователь кликает или нажимает пальцем другое окно или приложение (например, Notepad), то текущее окно с клавиатурой теряет активность. Поэтому можно предложить два решения:
при потере фокуса окна с клавиатурой использовать стили окна:
WS_EX_NOACTIVATE
WS_EX_TOPMOST
при коммуникации со сторонними приложениями запускать клавиатуру в отдельном потоке:
ThreadPool.QueueUserWorkItem(KeyboardLoop);
Несмотря на возраст технологии, реализованное решение можно использовать в нишевых или ограниченных системах:
киоски и терминалы
embedded-устройства
старые WinForms-приложения
Однако, если писать приложение сейчас, лучше использовать WPF, MAUI или web based приложение.
Весь проект выложен на GitHub по ссылке [2].
Там вы найдёте:
Полный код VirtualKeyboard
Демо-проект с примерами настройки
Готовые DLL для быстрого подключения
Автор: Practical_Developer
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/windows/450751
Ссылки в тексте:
[1] Архив оригинала: https://web.archive.org/web/20231202183633/https://www.codeproject.com/Articles/1172298/Touchscreen-GDIplus-Drawn-Keyboard
[2] ссылке: https://github.com/practicalDeveloper/Touchscreen-GDI-Drawn-Keyboard
[3] Источник: https://habr.com/ru/articles/1030360/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1030360
Нажмите здесь для печати.