В процессе эксплуатации систем на базе 1С:Предприятие 8 (особенно в конфигурациях с использованием Обычных форм) разработчики часто сталкиваются с ситуацией, когда после обновления платформы привычное поведение интерфейса меняется. Одной из наиболее раздражающих проблем является потеря фокуса (курсора) в поле ввода. Рассмотрим типичный сценарий: в обработке для охраны данные считываются с магнитной карты, и фокус должен автоматически возвращаться в поле Карта для следующего сканирования. Однако после обновления платформы до версии 8.3.15 и выше фокус «улетает» на другие элементы или вовсе исчезает.
В этой статье мы подробно проанализируем, почему это происходит, и разберем несколько эффективных способов программного принудительного позиционирования курсора.
Разберем ситуацию с технической точки зрения. В новых релизах платформы 8.3 разработчики 1С внесли значительные изменения в графическое ядро для поддержки современных мониторов с высоким разрешением (High-DPI). Это затронуло и старый движок отрисовки обычных форм. Когда закрывается модальное окно (например, Предупреждение или Вопрос), операционная система Windows и платформа 1С инициируют цепочку событий по перерисовке окон.
Часто возникает эффект «гонки событий»: ваш код по установке фокуса выполняется мгновенно, но сразу после этого платформа завершает процесс активации основного окна и возвращает фокус на тот элемент, который она «считает» последним активным, игнорируя ваши программные установки. Также на это может влиять параметр Режим использования модальности в свойствах конфигурации.
Это базовый способ, который должен работать в идеальных условиях. Мы обращаемся к свойству формы ТекущийЭлемент и присваиваем ему ссылку на нужный нам элемент управления. Рассмотрим пример кода, который обычно размещается в процедуре после обработки данных карты:
Процедура ПослеОбработкиДанных()
// Основная логика обработки карты
// ...
// Попытка вернуть фокус
ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.Карта;
КонецПроцедуры
Если этот код перестал работать после обновления, значит, выполнение процедуры завершается раньше, чем форма успевает окончательно стать активной. В таких случаях переходим к более надежным методам.
Проанализируем ситуацию: если прямая установка фокуса не помогает, нам нужно «отложить» это действие на долю секунды, чтобы платформа успела завершить все свои внутренние процессы активации окна. Для этого идеально подходит метод ПодключитьОбработчикОжидания.
Разберем реализацию по шагам:
Пример реализации:
Процедура ОбработкаОшибкиЧтения()
Предупреждение("Карта не найдена в базе данных!");
// Вызываем установку фокуса с задержкой в 0.1 секунды
ПодключитьОбработчикОжидания("ПринудительноВернутьФокус", 0.1, Истина);
КонецПроцедуры
Процедура ПринудительноВернутьФокус() Экспорт
ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.Карта;
// Дополнительно можно вызвать метод Активизировать()
ЭлементыФормы.Карта.Активизировать();
КонецПроцедуры
Важный момент: использование параметра Истина в методе ПодключитьОбработчикОжидания гарантирует, что процедура выполнится только один раз (однократное выполнение).
Иногда причина кроется в настройках самой формы. Посмотрим на свойства элементов управления:
АвтоПорядокОбхода, если вы хотите жестко контролировать перемещение курсора.Карта было первым. В режиме конфигурирования выберите пункт меню «Форма -> Порядок обхода».Карта. Это подскажет системе, что при активации группы элементов фокус должен попасть именно сюда.Этот метод считается «агрессивным», но иногда он является единственным выходом. Событие ОбновлениеОтображения вызывается платформой очень часто — практически при любом изменении состояния интерфейса или движении мыши.
Рассмотрим, как правильно прописать установку фокуса в этом событии, чтобы не зациклить программу:
Процедура ОбновлениеОтображения()
// Устанавливаем фокус только если он сейчас НЕ на нужном элементе
Если ЭтаФорма.ТекущийЭлемент <> ЭлементыФормы.Карта Тогда
ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.Карта;
КонецЕсли;
КонецПроцедуры
Внимание: Будьте осторожны с этим методом. Если пользователю когда-либо понадобится нажать на другую кнопку или ввести данные в другое поле, этот код будет постоянно «отбрасывать» его назад в поле Карта. Используйте этот способ только в специализированных АРМ (рабочих местах), где ввод данных возможен строго в одно поле.
Если выяснилось, что фокус пропадает именно после окна Предупреждение(), проанализируем возможность изменения логики оповещения. Модальные окна полностью перехватывают управление, что и вызывает проблемы в 8.3.
Попробуйте использовать метод Сообщить(). Сообщения выводятся в специальное окно в нижней части экрана, не прерывая поток выполнения кода и не забирая фокус у активного окна. Это позволит пользователю продолжить работу с картами без лишних кликов мышкой.
Мы рассмотрели основные способы решения проблемы потери фокуса в Обычных формах 1С. Наиболее эффективным и современным решением для платформы 8.3 является использование обработчика ожидания с минимальной задержкой. Это позволяет обойти архитектурные особенности обновления интерфейса и гарантированно позиционировать курсор в нужном поле ввода, обеспечивая комфортную работу сотрудников.