При разработке сложных интерфейсов в 1С:Предприятии 7.7 часто возникает задача динамического изменения размеров элементов управления. Например, если на форме расположены две связанные таблицы (список документов и строки выбранного документа), пользователю удобно менять их пропорции вручную с помощью разделителя — сплиттера. Разберем, как устроен этот механизм, нужно ли вручную отлавливать события перемещения мыши и какую обязательную строчку кода необходимо добавить для корректной работы разделителей.
В типовой платформе 1С 7.7 штатный функционал привязок и сплиттеров отсутствует. Для его реализации традиционно используются расширения платформы (такие как 1С++ и FormEx) и специализированные классы управления формой (например, класс Общие.Форма.Привязки).
Многие разработчики, добавив сплиттер на форму, пытаются вручную отловить события взаимодействия пользователя с разделителем, чтобы программно пересчитать координаты таблиц. Однако выясним главную особенность работы данного механизма: вручную перехватывать системные события перемещения сплиттера не требуется.
Класс привязок автоматически берет на себя перехват низкоуровневых событий мыши (WM_LBUTTONDOWN, WM_MOUSEMOVE, WM_LBUTTONUP) через переопределение оконной процедуры (subclassing). Как только пользователь перетаскивает сплиттер, класс самостоятельно вычисляет новые границы смежных элементов и обновляет их координаты.
Рассмотрим по шагам, как правильно настроить разделитель между двумя таблицами на форме обработки или документа:
ВертРазделительТаблиц.ПриОткрытии создаем экземпляр класса и связываем таблицы со сплиттером.Посмотрим на типовой пример кода инициализации привязок:
Процедура ПриОткрытии()
// Инициализируем объект класса привязок
оПривязки = СоздатьОбъект("Общие.Форма.Привязки");
оПривязки.УстановитьФорму(Форма);
// Добавляем сплиттер: имя сплиттера, первый элемент, второй элемент, шаг/минимальный размер
оПривязки.ДобавитьГорСплиттер("ВертРазделительТаблиц", "тпДоков_", "тпДокумента_", 8);
// Включаем слой формы для форсирования инициализации контролов
Форма.ИспользоватьСлой("Основной", 2);
КонецПроцедуры
Частая проблема, с которой сталкиваются разработчики: сплиттер на форме отображается, но при попытке перетащить его мышью ничего не происходит, и размеры таблиц не меняются. Проанализируем причину такого поведения.
Для того чтобы библиотека смогла управлять элементами формы и перехватывать их события, ей необходимо получить дескрипторы окон (HWND) всех контролов. В момент выполнения базовой части процедуры ПриОткрытии окна элементов формы еще не до конца инициализированы операционной системой.
Вызов метода со вторым параметром 2:
Форма.ИспользоватьСлой("Основной", 2);
активирует слой в режиме наложения без скрытия остальных элементов. Это принудительно завершает инициализацию оконных дескрипторов всех контролов на форме. После выполнения этой строки класс привязок успешно связывается с оконными процедурами элементов, и сплиттер начинает полноценно двигаться и изменять размеры соседних таблиц.
При использовании классов управления формой обратим внимание на следующие технические моменты:
ПриОткрытии или в предопределенном событии ПослеСозданияФормы.FormEx на время активного движения мыши.