При разработке интерфейсов для сенсорных экранов, POS-терминалов, мобильных рабочих мест или специализированных мониторов (например, на складах или в торговых залах) часто возникает необходимость реализовать собственную экранную клавиатуру. Типичный сценарий: пользователь должен видеть перед собой форму документа и форму экранной клавиатуры одновременно, при этом ввод данных должен осуществляться кликами по клавиатуре непосредственно в активное поле документа.
Основная сложность в управляемом интерфейсе «1С:Предприятие» (особенно в режиме «Такси») заключается в том, что стандартного свойства «Всегда сверху» (Always on Top) для неблокирующих окон платформы не предусмотрено. Если открыть форму клавиатуры как независимую, то любое нажатие на форму документа-владельца автоматически перенесет фокус на него, а окно клавиатуры мгновенно скроется на задний план. Использование свойства РежимОткрытияОкна = Блокировать окно владельца решает проблему видимости клавиатуры, но полностью блокирует возможность ввода данных и активации полей в самом документе. Рассмотрим, какие существуют архитектурные и технические решения этой проблемы.
Самым надежным и архитектурно правильным способом в рамках концепции управляемого приложения является отказ от отдельного окна клавиатуры в пользу встроенной панели прямо внутри формы документа. Чтобы не дорабатывать вручную каждую форму в конфигураторе, мы можем использовать механизм динамического создания элементов на сервере в сочетании с расширениями конфигурации.
Давайте разберем по шагам, как программно добавить панель с кнопками на форму документа:
ПриСозданииНаСервере.Посмотрим на пример реализации динамического создания цифровой панели на форме:
&НаСервере
Процедура ДобавитьПанельКлавиатурыНаФорму()
// Проверим, не создана ли группа ранее
Если Элементы.Найти("ГруппаЭкраннаяКлавиатура") = Неопределено Тогда
// Создаем основную группу-контейнер внизу формы
НоваяГруппа = Элементы.Добавить("ГруппаЭкраннаяКлавиатура", Тип("ГруппаФормы"), ЭтаФорма);
НоваяГруппа.Вид = ВидГруппыФормы.ОбычнаяГруппа;
НоваяГруппа.Отображение = ОтображениеПанелиОкна.Нет;
НоваяГруппа.Группировка = ГруппировкаПодчиненныхЭлементовФормы.ГоризонтальнаяЕслиВозможно;
// Создаем кнопки для цифр от 0 до 9
Для Индекс = 1 По 9 Цикл
ИмяКнопки = "КнопкаКлавиатуры_" + Индекс;
НоваяКнопка = Элементы.Добавить(ИмяКнопки, Тип("КнопкаФормы"), НоваяГруппа);
НоваяКнопка.ИмяКоманды = "НажатиеКнопкиКлавиатуры";
НоваяКнопка.Заголовок = Строка(Индекс);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
При таком подходе клавиатура становится неотъемлемой частью формы документа. Она физически не может «уйти» на задний план, так как расположена в том же самом окне. Управление видимостью панели (например, показывать её только при активизации определенных полей ввода) можно реализовать через изменение свойства Видимость созданной группы элементов.
Если стандартный внешний вид кнопок 1С вас не устраивает или требуется реализовать сложную раскладку клавиатуры с адаптивным дизайном, отличным решением станет использование элемента формы ПолеHTMLДокумента.
Этот способ обладает важным преимуществом: клики по кнопкам внутри HTML-поля обрабатываются браузерным движком платформы и не приводят к такой потере фокуса операционной системой, как переключение между независимыми окнами Windows. Рассмотрим подробнее, как организовать взаимодействие:
Поле HTML-документа.Разберем пример кода для обработки нажатия кнопки в HTML-поле:
&НаКлиенте
Процедура ПолеHTMLКлавиатурыПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка)
// Отменяем стандартную обработку перехода по ссылке в браузере
СтандартнаяОбработка = Ложь;
// Получаем идентификатор нажатого символа из параметров события
Если ДанныеСобытия.Свойства().Найти("id") <> Неопределено Тогда
НажатыйСимвол = ДанныеСобытия.id;
ВставитьСимволВТекущееПоле(НажатыйСимвол);
КонецЕсли;
КонецПроцедуры
Если по каким-то причинам клавиатуру крайне важно оставить именно в виде отдельного, независимого (неблокирующего) окна, нам придется программно управлять кареткой ввода и фокусом формы. Главная проблема здесь — при клике по кнопке на форме клавиатуры фокус немедленно уходит с поля ввода документа.
Чтобы вернуть фокус обратно в документ и дописать туда нужный символ, мы должны использовать обработчики событий и программно устанавливать текущий активный элемент. Проанализируем схему реализации:
ОповеститьОВыборе или вызов экспортного метода формы-владельца).Пример кода в форме документа для восстановления фокуса:
&НаКлиенте
Процедура ОбработатьВводСКлавиатуры(ЗначениеСимвола) Экспорт
// Определяем текущий редактируемый элемент формы
АктивныйЭлемент = ЭтаФорма.ТекущийЭлемент;
Если ТипЗнч(АктивныйЭлемент) = Тип("ПолеФормы") Тогда
// Дописываем символ в значение поля ввода
АктивныйЭлемент.ВыделенныйТекст = ЗначениеСимвола;
// Возвращаем фокус ввода на поле
ЭтаФорма.ТекущийЭлемент = АктивныйЭлемент;
КонецЕсли;
КонецПроцедуры
Важный лайфхак для сенсорных экранов и мобильных клиентов: на некоторых устройствах под управлением Android или специализированных тач-панелях простое присвоение ТекущийЭлемент может не приводить к появлению мигающего курсора. Проверенное решение разработчиков заключается во временном отключении видимости элемента на долю секунды:
// Принудительно перезапускаем фокус для сенсорного экрана
АктивныйЭлемент.Видимость = Ложь;
АктивныйЭлемент.Видимость = Истина;
ЭтаФорма.ТекущийЭлемент = АктивныйЭлемент;
Этот нехитрый прием заставляет платформу гарантированно перерисовать элемент формы и вернуть туда активную каретку ввода.
Если решение создается строго под настольные компьютеры или моноблоки под управлением ОС Windows, поведение «всегда сверху» для отдельного окна можно навязать на уровне операционной системы.
Для этого используется вызов системной функции WinAPI SetWindowPos с флагом HWND_TOPMOST. Реализовать это можно через:
Этот метод позволяет жестко закрепить окно виртуальной клавиатуры 1С поверх всех окон (включая основное окно самой платформы 1С). Пользователь сможет свободно кликать мышкой или пальцем по форме документа, при этом окно клавиатуры физически не сможет уйти на задний план.
Прежде чем приступать к разработке собственной клавиатуры с нуля, убедитесь, что вы задействовали встроенные возможности платформы «1С:Предприятие».
У каждого элемента формы типа «Поле ввода» (для числовых, текстовых и строковых данных) в палитре свойств доступно свойство ТипВиртуальнойКлавиатуры. Вы можете выбрать один из предопределенных вариантов:
Авто;ДесятичнаяКлавиатура;Телефон;URL;ЭлектроннаяПочта.При работе в мобильном клиенте или на современных сенсорных моноблоках с поддержкой экранного ввода Windows/Android, платформа самостоятельно вызовет оптимизированную системную клавиатуру нужного формата в момент активизации поля ввода. Это избавляет от необходимости писать и поддерживать сложный программный код экранных панелей.