При переходе на новые релизы платформы разработчики и системные администраторы нередко сталкиваются с неожиданным изменением поведения интерфейса. Разберем распространенную проблему: в толстом клиенте при использовании управляемых форм (в том числе в режиме обычного приложения или при интерфейсе «Формы в отдельных окнах») неактивная фоновая форма при периодическом обновлении данных принудительно перехватывает фокус ввода и перекрывает активные окна пользователя.
Проанализируем механику возникновения этой ошибки, выясним, почему не помогает изменение режима совместимости конфигурации, и рассмотрим рабочие способы устранения некорректного поведения окон.
Посмотрим на внутренние механизмы платформы. Такое поведение характерно для сборок платформы (в частности, релиза 8.3.9.1850), где была существенно переработана низкоуровневая архитектура маршрутизации оконных сообщений и перерисовки немодальных форм. В операционных системах семейств Windows управление окнами завязано на системные дескрипторы и вызовы оконного менеджера.
Выясним причину сбоя: при срабатывании фонового обновления (например, через свойство динамического списка ПериодАвтообновления, по таймеру метода ПодключитьОбработчикОжидания() или при серверном вызове) платформа ошибочно вызывает системную функцию активации окна (аналог SetForegroundWindow). В результате окно, которое должно было обновиться в фоновом режиме, перехватывает фокус у оператора, сбивая фокус ввода в других программах или соседних формах 1С (например, в рабочем месте кассира в конфигурации 1С:Розница).
Важный нюанс: изменение свойства конфигурации Режим совместимости (например, выставление значения «Версия 8.3.8») в данной ситуации не дает эффекта. Режим совместимости регулирует синтаксис встроенного языка, поведение транзакций, структуру таблиц базы данных и логику запросов, но не откатывает графический движок и оконный менеджер толстого или тонкого клиента к коду старой платформы.
Поскольку проблема локализована в программном коде самой платформы «1С:Предприятие», наиболее надежным и системным решением является корректировка используемой версии платформы.
8.3.8.2197 или 8.3.8.2270), где оконная подсистема отрабатывает обновление без принудительного всплытия окна.Если оперативно обновить платформу на рабочих местах пользователей невозможно, проанализируем программные обходные пути. Главный источник проблемы — регулярный опрос данных неактивным окном.
Разберем шаги по нейтрализации фонового вызова:
ПериодАвтообновления в значение 0.ПодключитьОбработчикОжидания(), исключим безусловный вызов обновления. Переведем обновление данных на стандартную кнопку панели «Обновить» (клавиша F5) либо добавим проверку необходимости обновления.Посмотрим на пример отключения циклического обработчика ожидания при закрытии или потере активности формы:
&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)
// Отключаем фоновое обновление формы
ОтключитьОбработчикОжидания("ОбновитьДанныеСписка");
КонецПроцедуры
Постоянный опрос базы данных раз в минуту не только провоцирует всплытие формы из-за бага оконного менеджера, но и создает лишнюю нагрузку на сервер 1С и СУБД. Заменим периодический таймер на механизм управляемых оповещений.
Разберем по шагам реализацию паттерна оповещения:
ОповеститьОбИзменении() или системный метод Оповестить().ОбработкаОповещения(). При таком подходе форма обновляется только тогда, когда это действительно нужно, снижая риск внезапных перехватов системного фокуса.Посмотрим на пример кода в модуле управляемой формы:
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "ЗаписанНовыйДокумент" Тогда
// Обновляем только элементы формы, не заставляя окно активироваться целиком
Элементы.Список.Обновить();
КонецЕсли;
КонецПроцедуры
Проанализируем еще одну архитектурную особенность: данная ошибка проявляется преимущественно при интерфейсе «Формы в отдельных окнах», характерном для толстого клиента обычного приложения и режима совместимости интерфейса. В таком режиме операционная система Windows воспринимает каждую форму как независимое системное окно.
Если специфика конфигурации позволяет использовать клиентское приложение в управляемом режиме («Такси» или формы в закладках), переведем рабочее место в интерфейс «Формы в закладках». Когда формы располагаются во вкладках единого родительского окна приложения, фоновый процесс перерисовки страницы не приводит к вызову SetForegroundWindow, и рабочее пространство пользователя не перекрывается.