При разработке конфигураций на платформе 1С:Предприятие 8.3 в режиме управляемого приложения часто требуется предотвратить случайное закрытие программы пользователем. В условиях отказа от модальных окон стандартный синхронный метод Вопрос() использовать нельзя. Разберем по шагам доступные способы реализации запроса на подтверждение выхода из системы.
Проанализируем самый простой и рекомендуемый платформой способ. В модуле управляемого приложения существует предопределенное событие ПередЗавершениемРаботыСистемы, которое принимает два параметра: Отказ и ТекстПредупреждения.
Если параметру Отказ присвоить значение Истина и заполнить ТекстПредупреждения, платформа 1С автоматически отобразит немодальный диалог с указанным текстом и предложит пользователю выбор — остаться в программе или завершить работу.
Посмотрим на пример кода в модуле управляемого приложения:
Процедура ПередЗавершениемРаботыСистемы(Отказ, ТекстПредупреждения)
Отказ = Истина;
ТекстПредупреждения = "Вы действительно хотите выйти из программы?";
КонецПроцедуры
Рассмотрим особенности работы данного метода:
Если требуется кастомизировать диалоговое окно (например, изменить набор кнопок или выполнить дополнительные проверки перед закрытием), используется метод ПоказатьВопрос(). Выясним причину частых ошибок при его реализации: поскольку метод является асинхронным, код процедуры ПередЗавершениемРаботыСистемы завершается до того, как пользователь успевает нажать кнопку в диалоге.
Чтобы диалог сработал корректно, необходимо отменить текущее закрытие системы через Отказ = Истина, а после положительного ответа пользователя вызвать программное завершение работы. Разберем по шагам реализацию этого механизма:
ЗавершениеРаботыКлиент). Модуль должен быть неглобальным, и у него должен быть установлен флаг Клиент (управляемое приложение).Посмотрим на пример кода в общем модуле ЗавершениеРаботыКлиент:
&НаКлиенте
Перем ЗавершениеРазрешено Экспорт;
&НаКлиенте
Процедура ПослеЗакрытияВопроса(Результат, ДополнительныеПараметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
ЗавершениеРазрешено = Истина;
ЗавершитьРаботуСистемы();
КонецЕсли;
КонецПроцедуры
Теперь рассмотрим код в модуле управляемого приложения:
Процедура ПередЗавершениемРаботыСистемы(Отказ, ТекстПредупреждения)
Если ЗавершениеРаботыКлиент.ЗавершениеРазрешено = Истина Тогда
Возврат;
КонецЕсли;
Отказ = Истина;
Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияВопроса", ЗавершениеРаботыКлиент);
ПоказатьВопрос(Оповещение, "Точно закрыть программу?", РежимДиалогаВопрос.ДаНет);
КонецПроцедуры
Проанализируем разницу между двумя методами завершения работы, так как выбор неправильного метода может привести к потере пользовательских данных:
ЗавершитьРаботуСистемы(): выполняет штатный выход. Платформа последовательно вызывает обработчики ПередЗакрытием и ПриЗакрытии для всех открытых окон, сохраняет пользовательские настройки динамических списков, форм и профиль интерфейса. Именно этот метод следует вызывать после подтверждения диалога.ПрекратитьРаботуСистемы(): производит аварийный/принудительный разрыв сеанса. При его вызове не сохраняются настройки пользователя и параметры форм, а обработчики закрытия игнорируются. Использовать его для стандартного выхода крайне не рекомендуется.Таким образом, для базовой задачи подтверждения выхода оптимально использовать штатный параметр ТекстПредупреждения, а при необходимости расширенной логики — связку из ПоказатьВопрос(), флага завершения в общем модуле и метода ЗавершитьРаботуСистемы().