首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无法获得所有使用EnumDisplaySettings的设备的显示分辨率

无法获得所有使用EnumDisplaySettings的设备的显示分辨率
EN

Stack Overflow用户
提问于 2020-02-09 21:32:59
回答 3查看 2.1K关注 0票数 3

我需要获得当前显示分辨率的所有显示器连接到计算机。

我可以使用EnumDisplayDevicesA API成功地启用显示设备,但是由于未知的原因,我无法使用EnumDisplayDevicesA API获得设备\.\ display 2的当前显示分辨率。以下是代码:

代码语言:javascript
运行
复制
displays = 0;
result = 1;

for (index = 0; result != 0; index++)
{
    devices[index].cb = sizeof(DISPLAY_DEVICEA);
    result = EnumDisplayDevicesA(NULL, index, &(devices[displays] ), 0);

    if (result == 0)
    {
            break;
    }

    settings[index].dmSize = sizeof(DEVMODEA);
    mode = 0;

    // Collect the settings
    while(EnumDisplaySettingsA(devices[index].DeviceName, mode, (DEVMODEA *)&(settings[displays] ) ) )
    {
        mode++;
    };

    // Read the current settings
    result = EnumDisplaySettingsA(devices[index].DeviceName, ENUM_CURRENT_SETTINGS, (DEVMODEA *)&(settings[displays] ) );

    if (result != 0)
    {
        displays++;
    }
    else 
    {
        result = GetLastError();
        printf("Error while readind display settings %d\n", result);

        //Skip this device
        result = 1;
    }
}

请注意,此代码在某些计算机上工作完美,而在具有多个显卡的计算机上则失败。例如,它在带有IntelHDGraphicw630+ Nvidia M1200的膝上型计算机上失败,其中活动显示器是主膝上型显示器,以及通过HDMI或DP端口附加的外部显示)。更准确地说,在这些计算机上,我可以获得第一个显示设备(\\ display 1)的正确分辨率,但在第二个显示设备(\.\ display 2)上,返回的宽度和高度是0。

EnumDisplaySettingsA API只返回0,以及GetLastError API。

设备代表什么?它们是连接到单个视频卡上的监视器,还是仅仅是连接到任何视频卡上的监视器?

注意:使用EnumDisplayMonitors,我可以在EnumDisplaySettingsA失败时获得所有监视器的分辨率。

EN

回答 3

Stack Overflow用户

发布于 2020-02-14 11:28:16

是否可以通过在EnumDisplayDevices上迭代获得两个以上的设备?

对我来说,有7个.\DISPLAYX条目,尽管我只有笔记本显示器和两个外部监视器。

当使用未连接的显示器调用EnumDisplaySettings时,结果与您的情况0类似。对我来说,DISPLAY1、DISPLAY4和DISPLAY5是我需要使用的。

票数 3
EN

Stack Overflow用户

发布于 2020-02-14 15:52:14

(DEVMODEA*)&(设置显示器)

您使用强制转换的事实表明,settings定义错误,而cast用于隐藏问题。例如,如果您声明了DEVMODEA *settings = malloc(count * sizeof(DEVMODEA)),那么就不需要强制转换了。

您应该使用Microsoft推荐的Unicode函数。如果需要打印ANSI,则使用WideCharToMultiByte将Unicode转换为ANSI。

此外,您正在下面的代码中覆盖settings[index]

结果= while(EnumDisplaySettingsA(devicesindex.DeviceName,(devicesindex.DeviceName,ENUM_CURRENT_SETTINGS,(DEVMODEA *)&(设置显示器) );

请注意,对EnumDisplaySettingsA的第二个调用使用ENUM_CURRENT_SETTINGS,此调用永远不会失败,并可能在您的循环中造成问题。它还将覆盖settings[displays]的前一个值。

试试下面的代码,看看是否有区别。

代码语言:javascript
运行
复制
int main()
{
    DISPLAY_DEVICE device = { 0 };
    device.cb = sizeof(DISPLAY_DEVICE);
    for(int index = 0;; index++)
    {
        if(!EnumDisplayDevices(NULL, index, &device, EDD_GET_DEVICE_INTERFACE_NAME))
            break;

#ifdef UNICODE
        wprintf(L"%s\n", device.DeviceName);
#else
        printf("%s\n", device.DeviceName);
#endif

        DEVMODE devmode = { 0 };
        devmode.dmSize = sizeof(DEVMODE);
        for(int modes = 0;; modes++)
        {
            if(!EnumDisplaySettings(device.DeviceName, modes, &devmode))
                break;
            printf("%d %d %d\n", 
                devmode.dmPelsWidth, 
                devmode.dmPelsHeight,
                devmode.dmDisplayFrequency);
        }
    }

    return 0;
}

或读取每个监视器的当前分辨率。

代码语言:javascript
运行
复制
int main()
{
    int count = 0;
    DISPLAY_DEVICE temp = { 0 };
    temp.cb = sizeof(DISPLAY_DEVICE);
    while(EnumDisplayDevices(NULL, count, &temp, EDD_GET_DEVICE_INTERFACE_NAME))
        count++;
    DEVMODE *settings = malloc(count * sizeof(DEVMODE));
    DISPLAY_DEVICE *devices = malloc(count * sizeof(DISPLAY_DEVICE));

    for (int index = 0; index < count; index++)
    {
        memset(&devices[index], 0, sizeof(DISPLAY_DEVICE));
        memset(&settings[index], 0, sizeof(DEVMODE));
        devices[index].cb = sizeof(DISPLAY_DEVICE);
        settings[index].dmSize = sizeof(DEVMODE);
        if(!EnumDisplayDevices(NULL, index, &devices[index], EDD_GET_DEVICE_INTERFACE_NAME))
            break;
        if(!EnumDisplaySettings(devices[index].DeviceName, ENUM_CURRENT_SETTINGS, &settings[index]))
            break;
    }

    for(int index = 0; index < count; index++)
    {
#ifdef UNICODE
        wprintf(L"%s ", devices[index].DeviceName);
#else
        printf("%s ",  devices[index].DeviceName);
#endif
        printf("%d %d %d\n", 
            settings[index].dmPelsWidth,
            settings[index].dmPelsHeight,
            settings[index].dmDisplayFrequency);
    }
    return 0;
}
票数 3
EN

Stack Overflow用户

发布于 2020-02-15 14:40:14

该问题与windows无关,也与浇铸无关。不需要铸造,所以我把它移走了。这是由于代码中的变量使用错误造成的。正如我所说的,我只需要每个监视器的当前分辨率,在devicessettings结构的每个索引上,我只需要与活动显示器相关的数据。这是通过使用displays变量来确保的,该变量仅在设备具有可读设置时才会递增。相反,index变量应该递增到每个循环,直到EnumEnumDisplayDevicesA失败。

不幸的是,我还使用了index来初始化结构并将设备名称传递给EnumDisplaySettingsA。是我的错。因此,我使用devices[displays]语句填充设备结构,而传递给EnumDisplaySettingsA的结构是devices[index]。换句话说,错误的名称被传递给API ant,这就是失败的原因。在某些计算机上,它是工作的,因为活动监视器是第一个,但是一旦DISPLAY1或DISPALY2没有连接,应用程序就会不正确地运行。

这是正确的代码:

代码语言:javascript
运行
复制
displays = 0;
result = 1;

for (index = 0; result != 0; index++)
{
    devices[displays].cb = sizeof(DISPLAY_DEVICEA);
    result = EnumDisplayDevicesA(NULL, index, &(devices[displays] ), 0);

    if (result == 0)
    {
            break;
    }

    settings[displays].dmSize = sizeof(DEVMODEA);
    mode = 0;

    // Cache the settings
    EnumDisplaySettingsA(devices[displays].DeviceName, 0, &(settings[displays] ) ) 

    // Read the current settings
    result = EnumDisplaySettingsA(devices[displays].DeviceName, ENUM_CURRENT_SETTINGS, &(settings[displays] ) );

    if (result != 0)
    {
        displays++;
    }
    else 
    {
        result = GetLastError();
        printf("Error while readind display settings %d\n", result);

        //Skip this device
        result = 1;
    }
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60141542

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档