Getfriendlyname вторичного монитора

Мне нужно получить имя устройства дополнительного монитора. Однако, когда я просто пытаюсь получить имя устройства, вывод DISPLAY1, DISPLAYV1 и так далее.

Однако мне требуется имя, отображаемое при проверке разрешения экрана, например, отображаемое здесь имя:

Во-первых, я не уверен, откуда я могу получить эту строку. Читая немного, я думаю, что это friendlyname устройства. Однако я не уверен, так как при вызове EnumDisplaySetting() дал мне Unhandled Exception: Could not access memory location когда эта функция вызывается. Так что я не смог точно определить, что такое дружеское имя. И я считаю, что необработанное исключение вызвано неправильным выделением памяти для DISPLAY_DEVICE для driverextra в DISPLAY_DEVICE. Я считаю, что это из-за этого:

Функция завершается ошибкой, если iModeNum больше, чем индекс последнего графического режима устройства отображения.

упоминается здесь

Также я не понял, сколько памяти нужно выделить для
DISPLAY_DEVICE->dmDriverExtra, как уже упоминалось в той же ссылке:

Перед вызовом EnumDisplaySettings установите для элемента dmSize значение sizeof(DEVMODE) и задайте для элемента dmDriverExtra размер в байтах дополнительного пространства, доступного для получения данных частного драйвера.

Так что мой вопрос разнообразен:

1) Сколько памяти нужно выделить для dmDriverExtra?

2) Является ли friendlyname правильным параметром, который мне нужен для доступа к имени, указанному на вкладке "Отображение" в разрешении экрана. Или, если нет, какой другой параметр мне нужен?

3) Это необработанное исключение вызвано неправильным распределением памяти или есть какая-то другая причина для этого?

4) Есть ли другие способы получить доступ к friendlyname вторичного монитора?

1 ответ

обновленный

Я переключился на использование PhysicalMonitorAPI вместо GetMonitorInfo. Я совместил оригинальное решение с первым. Это дает более разумный вывод, чем вы ожидаете (например, "Dell UH2313" вместо "\.\Display1").

Технически, вы должны размещать массив мониторов вместо использования жестко закодированного массива - но я никогда не видел, где dwCount будет инициализироваться чем-то большим, чем 1.

Эта программа прекрасно компилируется в Visual Studio, но вам нужно будет связать ее с dxva2.lib, чтобы получить определения для API-интерфейсов PhysicalMonitor.

#include <Windows.h>
#include <PhysicalMonitorEnumerationAPI.h>
#include <string>
#include <iostream>
#include <stdio.h>

BOOL __stdcall MyMonitorEnumProc
(
_In_ HMONITOR hMonitor,
_In_ HDC      hdcMonitor,
_In_ LPRECT   lprcMonitor,
_In_ LPARAM   dwData
)
{
    DWORD dwCount = 0;
    std::wstring strName(L"Unknown monitor name");
    PHYSICAL_MONITOR monitors[100] = {};
    MONITORINFOEX info = {};
    info.cbSize = sizeof(info);

    if (GetMonitorInfo(hMonitor, (LPMONITORINFO)&info))
    {
        strName = info.szDevice;
    }

    if (GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor, &dwCount) && (dwCount > 0) && (dwCount < ARRAYSIZE(monitors)))
    {
        if (GetPhysicalMonitorsFromHMONITOR(hMonitor, dwCount, monitors))
        {
            strName = monitors[0].szPhysicalMonitorDescription;

            DestroyPhysicalMonitors(dwCount, monitors);
        }
    }

    std::wcout << L"Monitor: " << strName << std::endl;

    return TRUE;
}

void printMonitorNames()
{
    EnumDisplayMonitors(NULL, NULL, MyMonitorEnumProc, NULL);
}

int _tmain(int argc, _TCHAR* argv[])
{
    printMonitorNames();
    return 0;
}

И стоит поспорить, что MyMonitorEnumProc будет вызываться первым для основного монитора. Все остальные мониторы перечисляются далее.

Другие вопросы по тегам