Как заблокировать окно владельца в обычном приложении 1С при открытии дочерней формы?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При разработке в среде 1С:Предприятие на обычных формах (например, в конфигурации «Управление производственным предприятием») программисты часто сталкиваются с тем, что стандартные механизмы блокировки окна владельца, привычные по тонкому клиенту, работают некорректно. В управляемом интерфейсе достаточно установить параметр РежимОткрытияОкна.БлокироватьОкноВладельца, и система сама позаботится о пользовательском опыте. Однако в обычном приложении окна работают в многодокументном интерфейсе (MDI), где дочернее окно часто открывается «оторванным» от родителя, позволяя пользователю случайно нажать кнопки в основном окне во время выполнения фонового процесса. Разберем, как грамотно реализовать блокировку окна владельца, не прибегая к жесткой модальности, которая парализует работу всей системы.

Проблема использования модального режима

Первое решение, которое обычно приходит на ум — использование метода ОткрытьМодально(). Давайте проанализируем, почему в современных реалиях это плохой выбор. Модальный режим полностью останавливает выполнение программного кода в точке вызова и блокирует весь интерфейс приложения, включая главное меню и другие открытые окна. Если наша задача — заблокировать только одно конкретное окно, из которого запущена операция, ОткрытьМодально() будет избыточным и неудобным для пользователя, особенно если параллельно нужно работать с другими справочниками или отчетами.

Способ 1. Программное управление доступностью элементов управления

Наиболее надежный и «родной» для платформы способ — это временное отключение интерактивных возможностей элементов формы владельца. Мы можем воздействовать как на форму в целом, так и на её отдельные составляющие. Рассмотрим пошагово, как это реализовать.

Многие разработчики советуют устанавливать свойство ТолькоПросмотр для всей формы. Однако, как показывает практика, этого недостаточно: кнопки в командных панелях и некоторые специфические элементы управления могут оставаться активными. Проанализируем более глубокий подход — отключение свойства Доступность.

Для блокировки окна можно использовать обращение к основной панели формы. Если в вашей форме все элементы расположены на одной родительской панели, достаточно одной строки кода:

ЭтаФорма.Панель.Доступность = Ложь;

Однако у этого метода есть существенный недостаток: при возврате доступности (Доступность = Истина) форма часто «теряет» фокус ввода. Система не понимает, какой элемент должен стать активным, и пользователю приходится кликать по форме мышкой, чтобы продолжить работу. Чтобы этого избежать, мы должны принудительно возвращать фокус после завершения операции. Для этой задачи можно использовать готовое решение для автоматического восстановления фокуса в формах подбора.

Универсальная процедура блокировки и разблокировки

Давайте разберем пример кода, который можно разместить в модуле формы владельца для корректного управления состоянием интерфейса:


Процедура УстановитьСостояниеБлокировки(БлокировкаАктивна)
    
    // Блокируем или разблокируем основные группы элементов
    ЭлементыФормы.ОсновнаяПанель.Доступность = НЕ БлокировкаАктивна;
    ЭлементыФормы.КоманднаяПанельФормы.Доступность = НЕ БлокировкаАктивна;
    
    // Дополнительно можно установить ТолькоПросмотр для всей формы
    ЭтаФорма.ТолькоПросмотр = БлокировкаАктивна;
    
    Если НЕ БлокировкаАктивна Тогда
        // Возвращаем фокус на форму, чтобы пользователь мог сразу продолжить ввод
        ЭтаФорма.Активизировать();
    КонецЕсли;
    
КонецПроцедуры

Эту процедуру следует вызывать непосредственно перед открытием формы ожидания и в обработчике оповещения о её закрытии.

Способ 2. Управление фокусом через событие «ПриАктивизации»

Если программное отключение доступности кажется слишком агрессивным или искажает внешний вид формы (элементы становятся серыми), можно использовать метод «прилипания» фокуса. Суть заключается в том, что при попытке пользователя переключиться на окно владельца, система будет мгновенно возвращать его обратно в окно длительной операции.

Для реализации этого метода выполним следующие шаги:

  1. В модуле формы владельца определим переменную, которая будет хранить ссылку на открытую форму ожидания.
  2. В событии формы ПриАктивизации пропишем логика возврата фокуса.

Посмотрим на пример реализации:


Перем ФормаОжидания Экспорт;

Процедура ПриАктивизации()
    // Если форма ожидания открыта, не даем пользователю работать с владельцем
    Если ФормаОжидания <> Неопределено И ФормаОжидания.Открыта() Тогда
        Попытка
            ФормаОжидания.Активизировать();
        Исключение
            // Обработка случая, если форма уже закрывается
        КонецПопытки;
    КонецЕсли;
КонецПроцедуры

Этот способ создает эффект «модальности для одного окна». Пользователь видит основное окно, но как только он пытается в нем что-то нажать, фокус перескакивает назад на окно индикатора прогресса.

Способ 3. Использование прозрачного слоя-заглушки

Рассмотрим визуально «чистый» способ, который часто применяется в веб-разработке, но вполне реализуем и в 1С. Мы можем программно создать на форме элемент управления (например, Панель без границ и текста), который будет перекрывать все остальные элементы.

Алгоритм действий:

Эта панель будет «съедать» все клики мыши, не давая им дойти до кнопок и полей ввода, расположенных под ней.

Особенности при работе с Управляемыми Формами в обычном приложении

Если вы открываете Управляемую Форму (УФ) из обычного приложения (например, в УПП 1.3 на платформе 8.3), важно правильно передать параметры открытия. Несмотря на специфику интерфейса, иногда срабатывает связка через владельца, если он передан корректно.

При вызове ОткрытьФорму обязательно убедитесь, что третьим параметром передается ЭтаФорма (объект текущей обычной формы). В некоторых релизах платформы 8.3 даже в обычном приложении это позволяет системе установить иерархическую связь окон на уровне операционной системы, что упрощает их совместное сворачивание и развертывание.

Также не забудьте про проверку в событии ПередЗакрытием формы владельца. Выясним причину: если пользователь попытается закрыть основное окно, пока идет фоновый процесс, это может привести к ошибкам в базе данных. Обязательно добавьте проверку состояния длительной операции:


Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
    Если ДлительнаяОперацияВПроцессе Тогда
        Предупреждение("Пожалуйста, дождитесь завершения операции!");
        Отказ = Истина;
    КонецЕсли;
КонецПроцедуры

Резюме и рекомендации

Мы проанализировали несколько способов блокировки окна владельца в обычных формах 1С. Наиболее стабильным и рекомендуемым является комбинированный подход:

  1. Установка свойства ТолькоПросмотр = Истина для формы.
  2. Программное отключение Доступность = Ложь для основных командных панелей и групп элементов.
  3. Принудительный вызов ЭтаФорма.Активизировать() после завершения блокировки для восстановления фокуса ввода.

Такой подход обеспечивает отличный пользовательский интерфейс, сохраняет работоспособность системы и предотвращает случайные ошибки ввода данных во время работы фоновых алгоритмов.

← На главную