Как определить ширину элемента управляемой формы 1С в пикселях?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке сложных интерфейсов на управляемых формах 1С программисты часто сталкиваются с необходимостью узнать точные размеры элементов управления (кнопок, полей ввода, таблиц) в физических пикселях. Это может потребоваться для позиционирования всплывающих окон, отрисовки графики или интеграции с внешними компонентами. Однако в среде «1С:Предприятие 8.3» задача осложняется тем, что платформа использует абстрактную систему единиц. Разберем подробно, как устроена верстка в 1С и какими способами можно получить реальные размеры элементов.

Концепция условных единиц или «попугаев»

Прежде всего, нам необходимо понять, почему свойство Ширина в конфигураторе часто не дает представления о реальном размере. В управляемом интерфейсе 1С введена единица измерения, которую разработчики в шутку называют «попугаями». На самом деле это условный символ, размер которого программно привязан к средним характеристикам системного шрифта.

Рассмотрим основные правила формирования ширины:

  1. Базовая единица: Обычно 1 единица ширины примерно соответствует ширине цифры «0» в текущем шрифте интерфейса.
  2. Автоматическая ширина: Если в свойствах элемента ширина установлена в значение 0, платформа рассчитывает её автоматически. Проанализируем ситуацию: для поля ввода со строковым типом данных длиной 100 символов платформа выделит больше места, чем для строки длиной 10 символов, даже если оба поля пусты.
  3. Распределение в группах: Если элементы находятся в горизонтальной группе, платформа стремится распределить доступное пространство между ними. По умолчанию элементы расширяются «поровну на брата», если не заданы иные коэффициенты растяжения.

Влияние масштабирования и DPI

Проанализируем современные реалии работы мониторов. Начиная с версии 8.3.14, платформа 1С корректно работает с высоким DPI. Это вносит дополнительную переменную в наши расчеты. Итоговая ширина элемента в пикселях является производной нескольких множителей:

ИтоговыеПиксели = БазовыеЕдиницы * КоэффициентШрифта * СистемныйМасштабDPI * ТекущийМасштабФормы

Важно помнить, что пользователь может в любой момент изменить масштаб формы через меню «Вид — Изменить масштаб». В этом случае свойство формы ТекущийМасштаб изменится, и все визуальные элементы пропорционально увеличатся или уменьшатся, при этом программная ширина в «символах» останется прежней.

Метод 1: Использование Поля HTML-документа для замеров

Один из самых изящных способов узнать ширину контейнера без использования внешних библиотек — это внедрение вспомогательного элемента ПолеHTMLДокумента. Этот метод особенно полезен, когда нужно узнать ширину области, в которой располагаются другие элементы.

Разберем алгоритм действий:

  1. Разместим на форме элемент ПолеHTMLДокумента и установим его растягивание по горизонтали так же, как у интересующего нас элемента.
  2. С помощью кода на встроенном языке загрузим в поле простую пустую страницу.
  3. Выполним JavaScript-код внутри этого поля для получения ширины body или конкретного div.

Пример реализации передачи данных из HTML обратно в 1С:


&НаКлиенте
Процедура УзнатьШирину()
    ТекстHTML = 
    "<html>
    |<body onload='window.location.hash = document.body.clientWidth'>
    |</body>
    |</html>";
    Элементы.ПолеHTML.УстановитьТекст(ТекстHTML);
КонецПроцедуры

&НаКлиенте
Процедура ПолеHTMLПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка)
    // Либо используем обработку навигации
    ШиринаВПикселях = ДанныеСобытия.Href; 
КонецПроцедуры

Этот метод позволяет получить честные пиксели, которые браузерный движок (используемый внутри 1С) выделил под отображение контента.

Метод 2: Использование WinAPI (для Тонкого и Толстого клиентов)

Если решение задачи требуется в среде Windows и вам необходима абсолютная точность для конкретной кнопки или поля, можно прибегнуть к вызовам функций операционной системы. Этот путь сложнее, так как управляемые формы 1С не предоставляют прямой дескриптор (HWND) каждого элемента управления.

Рассмотрим последовательность действий для реализации через WinAPI:

  1. Получение HWND основного окна: Используем функции для поиска окна по заголовку или через активное окно приложения.
  2. Перебор дочерних окон: Поскольку каждый элемент в 1С (в Windows-клиенте) технически является отдельным окном или отрисовывается в рамках общего контейнера, нам нужно найти нужный дескриптор.
  3. Функция GetWindowRect: После нахождения дескриптора вызываем системную функцию, которая возвращает структуру с координатами (Top, Left, Right, Bottom).

Проанализируем математику: Ширина = Right - Left. Полученное значение будет в системных пикселях. Однако помните, что этот метод не сработает в веб-клиенте или на операционных системах, отличных от Windows.

Метод 3: Математический расчет на основе свойств окна

Существует еще один способ, позволяющий оценить размеры без сложных манипуляций с API. У объекта ОкноКлиентскогоПриложения доступны свойства Ширина и Высота. Они возвращают размеры окна в пикселях.

Посмотрим на пример логики расчета:

Если у нас есть форма, занимающая всё окно, и на ней расположена группа элементов с известными пропорциями, мы можем вычислить примерную ширину. Допустим, общая ширина окна 1200 пикселей. Форма имеет левый и правый отступы. Внутри находится группа, разделенная на две колонки. Зная коэффициенты растяжения, мы можем математически предположить, что ширина одной колонки составляет около 580-590 пикселей. Однако стоит учитывать, что погрешность из-за внутренних отступов (paddings) платформы может составлять до 10-15 пикселей.

Ограничения и рекомендации

Выясним причину, по которой 1С скрывает эти данные. Основная идеология управляемого приложения — независимость от устройства отображения. Один и тот же интерфейс должен адекватно выглядеть и на мониторе 4K, и на планшете, и в браузере смартфона.

Важные моменты для запоминания:

В заключение отметим, что наиболее надежным современным способом получения размеров является использование внешних компонент (Native API). Они позволяют корректно обходить ограничения платформы и получать доступ к иерархии окон операционной системы, возвращая точные координаты элементов управления в реальном времени.

← На главную