Как определить разрешение и ориентацию второго монитора в 1С 7.7

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

В современных рабочих процессах использование двух и более мониторов стало стандартом. Для разработчика на платформе 1С 7.7 это создает определенные трудности, так как штатные средства платформы ограничены в работе с графической подсистемой Windows. Особенно остро стоит вопрос, когда второй монитор используется в портретном режиме (вертикально), и интерфейс программы должен адаптироваться под эти условия. В этой статье мы подробно разберем несколько способов получения данных о мониторах: от стандартных WMI-запросов до использования профессиональных внешних компонент.

Метод 1. Использование WMI (Windows Management Instrumentation)

Проанализируем самый доступный способ, не требующий установки дополнительных библиотек. WMI позволяет обращаться к системным классам Windows для получения информации об аппаратном обеспечении. Для работы с мониторами в 1С 7.7 мы будем использовать объект WbemScripting.SWbemLocator.

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

Выясним причину: класс Win32_DesktopMonitor считается устаревшим. Тем не менее, во многих конфигурациях он все еще работает. Посмотрим на реализацию:


// Создаем объект для работы с WMI
Локатор = СоздатьОбъект("WbemScripting.SWbemLocator");
СервисWMI = Локатор.ConnectServer(".", "root\cimv2");

// Выполняем запрос к мониторам
Мониторы = СервисWMI.ExecQuery("Select * from Win32_DesktopMonitor");

Выборка = ИзВыборки(Мониторы); // Вспомогательная функция для обхода коллекции
Пока Выборка.Следующий() = 1 Цикл
    Ширина = Выборка.Объект.ScreenWidth;
    Высота = Выборка.Объект.ScreenHeight;
    Сообщить("Монитор: " + Ширина + "x" + Высота);
КонецЦикла;

Важное замечание: Если ScreenWidth и ScreenHeight возвращают пустое значение (Null), это означает, что система не может получить данные напрямую через этот класс. В таком случае проанализируем альтернативный класс — Win32_VideoController, который содержит информацию о текущем видеорежиме контроллера.


ВидеоКонтроллеры = СервисWMI.ExecQuery("Select * from Win32_VideoController");
ВыборкаВК = ИзВыборки(ВидеоКонтроллеры);
Пока ВыборкаВК.Следующий() = 1 Цикл
    ТекШирина = ВыборкаВК.Объект.CurrentHorizontalResolution;
    ТекВысота = ВыборкаВК.Объект.CurrentVerticalResolution;
    Сообщить("Активное разрешение контроллера: " + ТекШирина + "x" + ТекВысота);
КонецЦикла;

Метод 2. Использование внешней компоненты FormEx

Разберем наиболее надежный и профессиональный метод для 1С 7.7 — использование библиотеки FormEx. Эта компонента была создана специально для расширения интерфейсных возможностей платформы и имеет прямой доступ к Windows API.

Для решения нашей задачи в FormEx существует объект Сервис, который предоставляет методы для работы с многомониторными системами. В отличие от WMI, этот метод работает мгновенно и корректно определяет координаты мониторов даже в сложных конфигурациях.

Выполним следующие шаги для получения данных:

  1. Загрузим компоненту FormEx.dll.
  2. Создадим объект Сервис.
  3. Используем метод КоличествоМониторов() для определения общего числа экранов.
  4. В цикле получим координаты каждого монитора методом ПолучитьКоординатыМонитора().

Рассмотрим пример реализации на языке 1С 7.7:


Если ЗагрузитьВнешнююКомпоненту("FormEx.dll") = 0 Тогда
    Предупреждение("Компонента FormEx не найдена!");
    Возврат;
КонецЕсли;

Сервис = СоздатьОбъект("Сервис");
КолВо = Сервис.КоличествоМониторов();

Для Индекс = 1 По КолВо Цикл
    // Метод возвращает строку координат: "Left;Top;Right;Bottom"
    СтрКоординат = Сервис.ПолучитьКоординатыМонитора(Индекс);
    
    // Разберем строку (можно использовать функцию глРазложить или аналоги)
    // Допустим, мы получили координаты: "1920;0;3000;1920"
    // Ширина = Right - Left
    // Высота = Bottom - Top
    
    Сообщить("Монитор №" + Индекс + ": " + СтрКоординат);
    
    // Определение ориентации
    // Если (Bottom - Top) > (Right - Left) Тогда
    //     Сообщить("Ориентация: Портретная");
    // Иначе
    //     Сообщить("Ориентация: Ландшафтная");
    // КонецЕсли;
КонецЦикла;

Метод 3. Работа через Windows API (GetSystemMetrics)

Если мы не хотим использовать тяжелые компоненты, но нам нужно понять общие размеры рабочего стола, мы можем обратиться к функции GetSystemMetrics из библиотеки User32.dll. Для этого в 1С 7.7 обычно используется 1C++ или DynamicWrapper.

Проанализируем параметры, которые помогут нам вычислить параметры второго монитора:

Зная ширину всего виртуального пространства и ширину первого монитора, мы можем вычислить параметры второго. Однако помните, что этот метод эффективен только если мониторы стоят в ряд горизонтально.

Метод 4. Современный подход через PowerShell

В современных операционных системах (Windows 10/11) информация о мониторах наиболее точно отдается через PowerShell. Мы можем вызвать короткий скрипт из 1С, сохранить результат в текстовый файл и прочитать его.

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

1. Сформируем команду PowerShell, которая обращается к пространству имен root\wmi. Класс WmiMonitorBasicDisplayParams содержит данные о физических характеристиках, а Get-CimInstance позволяет получить активные настройки.


Команда = "powershell -Command ""Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorBasicDisplayParams | Out-File C:\monitors.txt""";
КомандаСистемы(Команда);

2. После выполнения команды прочитаем файл C:\monitors.txt штатными средствами 1С (объект Текст) и извлечем данные.

Сводная таблица выбора метода

Подводя итог, выберем оптимальный путь в зависимости от условий задачи:

  1. Если разрешено использование ВК: Однозначно используйте FormEx. Это самый быстрый и стабильный способ, который не зависит от прав доступа к WMI и корректно обрабатывает ориентацию (портрет/ландшафт).
  2. Если нужно решение без внешних файлов: Используйте WMI через класс Win32_VideoController. Он надежнее, чем Win32_DesktopMonitor, так как берет данные из текущих настроек видеоадаптера.
  3. Для системных администраторов: Использование PowerShell через КомандаСистемы позволит получить максимально детальную информацию, включая серийные номера и модели мониторов, что может быть полезно для инвентаризации.

Помните, что при работе с координатами мониторов в Windows, координаты могут быть отрицательными (например, если второй монитор расположен слева от основного). Всегда используйте модуль разности (абсолютное значение) при вычислении ширины и высоты через координаты Left, Right, Top и Bottom.

← На главную