Создаем разделитель (сплиттер) на форме с помощью FormEx. Вместо предисловия:
Большое спасибо Альфу за FormEx, без которого этой статьи не было бы.
Итак, мы решили исправить еще одну недоработку фирмы 1С и привинтить к форме разделитель (сплиттер). Для этого нам понадобиться установленный FormEx или 1С++.
Готовый пример лежит тут: webfile.ru/977920
Для начала создадим новую обработку. Кнопку Выход поместим в самый верх формы. У формы снимем галочку «Изменять размер», все равно весь процесс будем контролировать сами.
Далее возникает сложность. В наборе атрибутов формы нет ничего, что напоминало бы сплиттер, никакой полосы. Если добавить кнопку, она будет слишком широкая. Я вставил рамку, ужав ее до минимума и стерев заголовок, получилось нечто похожее. Правда настоящая ширина несколько больше, что добавит нам потом лишние хлопоты. Название зададим кнРазделения.
Далее объявляем несколько переменных и инициализируем их в процедуре ПриОткрытии:
Перем кнРазд;
Перем гРФорма;
Перем Кразд; //расстояние от разделителя до нижней границы формы
Перем Захват; //произведен ли захват сплиттера
Перем Наж; //сохраненное состояние кнопок мыши
//*******************************************
Процедура ПриОткрытии ()
кнРазд = СоздатьОбъект("АтрибутФормы");
кнРазд.УстановитьАтрибут(Форма,"кнРазделения");
гРФорма = СоздатьОбъект("РасширениеФормы");
Кразд = 0;
КонецПроцедуры //ПриОткрытии
Далее нам нужно сэмулировать захват и перетаскивание сплиттера. В этом нам поможет процедура ПриДвиженииМыши из набора FormEx.
//*******************************************
Процедура СдвинутьЭлементы()
кнРазд.УстановитьКоординаты(,гРФорма.Высота - Кразд - 12,,);
КонецПроцедуры //СдвинутьЭлементы()
//*******************************************
Процедура ПриДвиженииМыши(СостКнопок,кХ,кУ,ФСО)
Если Наж <> СостКнопок Тогда
//изменилось состояние кнопок мыши
Если (СостКнопок = 1) Тогда
//если нажата левая кнопка мыши
Если (кУ >= гРФорма.Высота - Кразд - 2) и (кУ <= гРФорма.Высота - Кразд + 2) Тогда
//если курсор находится на сплиттере
Захват = 1; //производим захват
СдвинутьЭлементы(); //передвигаем элементы
КонецЕсли;
Иначе
//если нажата НЕ левая кнопка
Захват = 0;
КонецЕсли;
//сохраним состояние кнопок
Наж = СостКнопок;
ИначеЕсли Захват = 1 Тогда
//если состояние кнопок не изменилось и был захват
Кразд = гРФорма.Высота - кУ; //сохраняем расстояние снизу
СдвинутьЭлементы(); //передвигаем элементы
КонецЕсли;
Если (кУ >= гРФорма.Высота - Кразд - 2) и (кУ <= гРФорма.Высота - Кразд + 2) Тогда
кнРазд.УстановитьКурсор(9);
Иначе
кнРазд.УстановитьКурсор(0);
КонецЕсли;
КонецПроцедуры //ПриДвиженииМыши
Также для нормального открытия формы добавим процедуру ПослеОткрытия. Опять же из FormEx.
//*******************************************
Процедура ПослеОткрытия()
кнРазд.УстановитьКоординаты(,,гРФорма.Ширина-15,);
Кразд = 20;
СдвинутьЭлементы();
КонецПроцедуры //ПослеОткрытия()
Проводим испытание, запускаем обработку, наводим указатель на сплиттер, таскаем его.
Пробуем изменить размер формы и сразу натыкаемся на проблему. Во-первых: не меняется ширина сплиттера вслед за формой, во-вторых: при уменьшении высоты формы сплиттер остается на месте и может пропасть за границей формы.
Решаем проблему опять же с помощью FormEx и процедуры ПриИзмененииРазмераОкна:
//*******************************************
Процедура ПриИзмененииРазмераОкна(ТипСобытия,НовШирина,НовВысота)
кнРазд.УстановитьКоординаты(,,НовШирина-15,);
СдвинутьЭлементы();
КонецПроцедуры //ПриИзмененииРазмераОкна
Дальше еще замечание: сплиттер подтягивается к самой границе окна, что не есть хорошо, ведь там будут размещаться другие элементы. Исправляем:
//*******************************************
Процедура ПриИзмененииРазмераОкна(ТипСобытия,НовШирина,НовВысота)
//не даем сделать форму меньше положенного
Если гРФорма.Высота < 160 Тогда
гРФорма.Высота = 160;
КонецЕсли;
кнРазд.УстановитьКоординаты(,,НовШирина-15,);
СдвинутьЭлементы();
КонецПроцедуры //ПриИзмененииРазмераОкна
//*******************************************
Процедура СдвинутьЭлементы()
Если Кразд < 60 Тогда
//проверяем размер снизу
Кразд = 60;
ИначеЕсли гРФорма.Высота - Кразд < 100 Тогда
//проверяем размер сверху
Кразд = гРФорма.Высота - 100;
КонецЕсли;
кнРазд.УстановитьКоординаты(,гРФорма.Высота - Кразд - 12,,);
КонецПроцедуры //СдвинутьЭлементы()
Итак, сплиттер сделан и работает, продолжим.
Добавим на форму таблицу значений, назовем ТЗ1, поставим ее над сплиттером.
Добавим:
В переменные: Перем Таб1;
В ПриОткрытии:
Таб1 = СоздатьОбъект("АтрибутФормы");
Таб1.УстановитьАтрибут(Форма,"ТЗ1");
В ПослеОткрытия (в самое начало):
Таб1.УстановитьКоординаты(,,гРФорма.Ширина-15,);
В ПриИзмененииРазмераОкна (в середину):
Таб1.УстановитьКоординаты(,,НоваяШирина-15,);
В СдвинутьЭлементы (в конец):
Таб1.УстановитьКоординаты(,,,гРФорма.Высота - Кразд - 45);
Можно пробовать, расстояние между сплиттером и нижней границей таблицы регулируется последней цифрой в последнем куске кода (в обратной пропорции).
Займемся второй таблицей. Добавим ее на форму ниже сплиттера и назовем ТЗ2.
Добавим:
В переменные: Перем Таб2;
В ПриОткрытии:
Таб2 = СоздатьОбъект("АтрибутФормы");
Таб2.УстановитьАтрибут(Форма,"ТЗ2");
В ПослеОткрытия (в самое начало):
Таб2.УстановитьКоординаты(,,гРФорма.Ширина-15,);
В ПриИзмененииРазмераОкна (в середину):
Таб2.УстановитьКоординаты(,,НоваяШирина-15,);
В СдвинутьЭлементы (в конец):
Таб2.УстановитьКоординаты(,гРФорма.Высота - Кразд + 6,,Кразд - 10);
Расстояние от сплиттера регулируется первым числом в последнем куске кода (в прямой пропорции), от нижней границы форма – вторым числом (в обратной пропорции).
|