В современных рабочих процессах использование двух и более мониторов стало стандартом. Для разработчика на платформе 1С 7.7 это создает определенные трудности, так как штатные средства платформы ограничены в работе с графической подсистемой Windows. Особенно остро стоит вопрос, когда второй монитор используется в портретном режиме (вертикально), и интерфейс программы должен адаптироваться под эти условия. В этой статье мы подробно разберем несколько способов получения данных о мониторах: от стандартных WMI-запросов до использования профессиональных внешних компонент.
Проанализируем самый доступный способ, не требующий установки дополнительных библиотек. 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" + ТекВысота);
КонецЦикла;
Разберем наиболее надежный и профессиональный метод для 1С 7.7 — использование библиотеки FormEx. Эта компонента была создана специально для расширения интерфейсных возможностей платформы и имеет прямой доступ к Windows API.
Для решения нашей задачи в FormEx существует объект Сервис, который предоставляет методы для работы с многомониторными системами. В отличие от WMI, этот метод работает мгновенно и корректно определяет координаты мониторов даже в сложных конфигурациях.
Выполним следующие шаги для получения данных:
FormEx.dll.Сервис.КоличествоМониторов() для определения общего числа экранов.ПолучитьКоординатыМонитора().Рассмотрим пример реализации на языке 1С 7.7:
Если ЗагрузитьВнешнююКомпоненту("FormEx.dll") = 0 Тогда
Предупреждение("Компонента FormEx не найдена!");
Возврат;
КонецЕсли;
Сервис = СоздатьОбъект("Сервис");
КолВо = Сервис.КоличествоМониторов();
Для Индекс = 1 По КолВо Цикл
// Метод возвращает строку координат: "Left;Top;Right;Bottom"
СтрКоординат = Сервис.ПолучитьКоординатыМонитора(Индекс);
// Разберем строку (можно использовать функцию глРазложить или аналоги)
// Допустим, мы получили координаты: "1920;0;3000;1920"
// Ширина = Right - Left
// Высота = Bottom - Top
Сообщить("Монитор №" + Индекс + ": " + СтрКоординат);
// Определение ориентации
// Если (Bottom - Top) > (Right - Left) Тогда
// Сообщить("Ориентация: Портретная");
// Иначе
// Сообщить("Ориентация: Ландшафтная");
// КонецЕсли;
КонецЦикла;
Если мы не хотим использовать тяжелые компоненты, но нам нужно понять общие размеры рабочего стола, мы можем обратиться к функции GetSystemMetrics из библиотеки User32.dll. Для этого в 1С 7.7 обычно используется 1C++ или DynamicWrapper.
Проанализируем параметры, которые помогут нам вычислить параметры второго монитора:
SM_CMONITORS (константа 80) — возвращает количество мониторов.SM_CXVIRTUALSCREEN (константа 78) — ширина всего виртуального экрана (сумма всех мониторов).SM_CYVIRTUALSCREEN (константа 79) — высота всего виртуального экрана.SM_CXSCREEN (константа 0) — ширина основного монитора.Зная ширину всего виртуального пространства и ширину первого монитора, мы можем вычислить параметры второго. Однако помните, что этот метод эффективен только если мониторы стоят в ряд горизонтально.
В современных операционных системах (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С (объект Текст) и извлечем данные.
Подводя итог, выберем оптимальный путь в зависимости от условий задачи:
FormEx. Это самый быстрый и стабильный способ, который не зависит от прав доступа к WMI и корректно обрабатывает ориентацию (портрет/ландшафт).Win32_VideoController. Он надежнее, чем Win32_DesktopMonitor, так как берет данные из текущих настроек видеоадаптера.КомандаСистемы позволит получить максимально детальную информацию, включая серийные номера и модели мониторов, что может быть полезно для инвентаризации.Помните, что при работе с координатами мониторов в Windows, координаты могут быть отрицательными (например, если второй монитор расположен слева от основного). Всегда используйте модуль разности (абсолютное значение) при вычислении ширины и высоты через координаты Left, Right, Top и Bottom.