В платформе 1С 7.7 разработчики часто сталкиваются с проблемой «разъезжающегося» интерфейса. Это происходит из-за того, что размеры элементов управления на форме по умолчанию привязаны к настройкам шрифта в профиле пользователя (Меню — Сервис — Параметры — Интерфейс — Шрифты — Формы). Если пользователь устанавливает увеличенный шрифт, например, MS Sans Serif 12 вместо стандартного 8, платформа автоматически масштабирует все элементы. Однако, если для формы заданы жесткие размеры через Окно.РазмерОкна в компоненте FormEx, содержимое перестает вмещаться в границы окна.
В данной статье мы разберем несколько способов решения этой задачи: от самого простого изменения свойств формы до продвинутого программного управления через внешние компоненты и WinAPI.
Разберем наиболее эффективный и не требующий написания сложного кода метод. Проблема масштабирования возникает из-за того, что в свойствах формы включена опция использования шрифта по умолчанию. Когда эта опция активна, 1С 7.7 пересчитывает все координаты и размеры из диалоговых единиц (Dialog Units, DBU) в пиксели на основе текущего выбранного пользователем шрифта.
Для решения проблемы выполним следующие шаги:
После этого форма перестанет реагировать на глобальные настройки шрифтов пользователя в меню «Параметры». Элементы будут отрисовываться ровно так, как они были расположены в конфигураторе, независимо от того, какой размер шрифта установлен у конкретного бухгалтера или оператора.
Рассмотрим ситуацию, когда нам все же нужно временно изменить шрифт для всей системы перед открытием формы, а затем вернуть его обратно. Этот метод считается «костылем», но он работоспособен в рамках компоненты FormEx. Проанализируем пример кода, который позволяет манипулировать объектом НастройкиПользователя.
// Создаем объекты компоненты FormEx
НастройкиПользователя = СоздатьОбъект("НастройкиПользователя");
Сервис = СоздатьОбъект("Сервис");
// Запоминаем текущий шрифт, чтобы потом его вернуть
СтарыйШрифт = НастройкиПользователя.ШрифтФорм;
// Устанавливаем нужный нам шрифт программно
НастройкиПользователя.ШрифтФорм = Сервис.СоздатьШрифт("Arial", 10, 7);
// Открываем нашу форму
ОткрытьФорму("Обработка.МояОбработка");
// Возвращаем настройки на место (важно сделать это после открытия)
НастройкиПользователя.ШрифтФорм = СтарыйШрифт;
Этот подход имеет существенный минус: если в момент открытия формы произойдет программная ошибка, настройки шрифта у пользователя могут остаться измененными для всей системы 1С. Поэтому рекомендуется использовать первый способ со снятием галочки в свойствах формы.
Выясним причину, по которой Окно.РазмерОкна иногда работает некорректно при разных шрифтах. 1С 7.7 использует Dialog Units. Одна единица по горизонтали равна 1/4 средней ширины символа шрифта, а по вертикали — 1/8 средней высоты. Если мы жестко задаем размер в пикселях через РазмерОкна(Форма, 800, 600), а шрифты увеличились, то содержимое формы потребует, например, 1000 пикселей, и нижние кнопки просто «уйдут» за границы.
Для профессионального решения задачи мы можем вычислить коэффициент масштабирования. Проанализируем ситуацию: если стандартный шрифт 8, а установлен 10, коэффициент составит 1.25. Мы можем программно обойти все элементы управления формы и изменить их шрифт массово, используя WinAPI сообщение WM_SETFONT. Это позволяет не трогать системные настройки, но жестко задать шрифт для конкретного окна через его HWND.
Используя расширение 1С++ или FormEx, мы можем перехватить событие ПриОткрытии и выполнить следующий алгоритм:
В ходе обсуждения часто возникает сопутствующий вопрос: как предотвратить вызов стандартной справки Windows по клавише F1, если мы хотим назначить на эту кнопку свое действие? В стандартной 1С 7.7 даже при использовании СтатусВозврата(0) в процедуре ПриНажатииКлавиши(), системное событие часто «пробрасывается» дальше, и окно справки открывается.
Рассмотрим, как это решается с помощью FormEx. Нам понадобится метод ВключитьПерехватКлавиш().
Процедура ПриОткрытии()
Сервис = СоздатьОбъект("Сервис");
Сервис.ВключитьПерехватКлавиш();
КонецПроцедуры
Процедура ПриНажатииКлавиши(Код, Флаги, Статус)
// Код клавиши F1 равен 112
Если Код = 112 Тогда
Предупреждение("Собственное действие вместо справки!");
// Устанавливаем Статус в 0, чтобы 1С не получила это событие
Статус = 0;
КонецЕсли;
КонецПроцедуры
Важный нюанс: если вы не хотите использовать программный перехват, можно прибегнуть к хитрости с «акселераторами». Создайте на форме кнопку, сделайте её невидимой (снимите флаг «Видимость»), а в свойствах кнопки в поле «Акселератор» выберите F1. В формуле кнопки напишите вызов своей процедуры. В большинстве случаев это перехватывает нажатие раньше, чем сработает системный вызов Help.
Подводя итог, можно сказать следующее. Если ваша задача — просто сохранить верстку формы при изменении шрифтов у пользователей, всегда начинайте со снятия флажка «Шрифт по умолчанию» в конфигураторе. Это самое стабильное решение, не зависящее от внешних компонент.
Если же вы строите сложный интерфейс (например, для ТСД или сенсорных киосков), где требуется динамическое изменение размеров, используйте возможности FormEx:
ПослеОткрытия() для изменения размеров окна, когда оно уже полностью сформировано.РасширениеФормы для задания «привязок» (anchors) элементов, чтобы они растягивались вместе с окном.Помните, что 1С 7.7 чувствительна к настройкам DPI операционной системы. При разработке на современных мониторах с масштабированием 125% или 150%, формы в конфигураторе могут выглядеть иначе, чем в режиме предприятия. Тестируйте интерфейс при стандартных 96 DPI для обеспечения максимальной совместимости.