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