Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Can';无法使用EnumDisplaySettings获取所有设备的显示分辨率_C_Windows_Winapi_Gdi - Fatal编程技术网

Can';无法使用EnumDisplaySettings获取所有设备的显示分辨率

Can';无法使用EnumDisplaySettings获取所有设备的显示分辨率,c,windows,winapi,gdi,C,Windows,Winapi,Gdi,我需要获取连接到计算机的所有监视器的当前显示分辨率 我可以使用EnumDisplayDevicesAAPI成功枚举显示设备,但由于未知原因,我无法使用EnumDisplayDevicesAAPI获取设备的当前显示分辨率。\DISPLAY2。 代码如下: displays = 0; result = 1; for (index = 0; result != 0; index++) { devices[index].cb = sizeof(DISPLAY_DEVICEA); res

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

我可以使用EnumDisplayDevicesAAPI成功枚举显示设备,但由于未知原因,我无法使用EnumDisplayDevicesAAPI获取设备的当前显示分辨率。\DISPLAY2。 代码如下:

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;
    }
}
请注意,此代码在某些计算机上工作正常,而在具有多个视频卡的计算机上则会出现故障。例如,在配备Intel HD Graphicw 630+Nvidia Quadro M1200的笔记本电脑上,它会出现故障,其中活动显示器是笔记本电脑的主显示器,外部显示器通过HDMI或DP端口连接)。更准确地说,在这些计算机上,我可以获得第一个显示设备(\\.\DISPLAY1)的正确分辨率,但在第二个显示设备(\\.\DISPLAY2)上,返回的宽度和高度为0

EnumDisplaySettingsAAPI只返回0以及GetLastErrorAPI

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


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

是否可以通过迭代EnumDisplayDevices获得两个以上的设备?
对我来说,有7个\.\DISPLAYX条目,尽管我只有笔记本电脑显示器和两个外部显示器。
当使用未连接的显示器调用EnumDisplaySettings时,结果与您的案例0类似。对我来说,DISPLAY1、DISPLAY4和DISPLAY5是我需要使用的

使用强制转换的事实表明
设置
定义不正确,强制转换用于隐藏问题。例如,如果您已声明,
DEVMODEA*settings=malloc(count*sizeof(DEVMODEA))
则不需要强制转换

您只需使用Microsoft推荐的Unicode函数即可。如果需要打印ANSI,请使用
WideCharToMultiByte
将Unicode转换为ANSI

此外,您正在覆盖下面代码中的设置[索引]:

请注意,对
EnumDisplaySettingsA
的第二次调用使用
ENUM\u CURRENT\u设置
,此调用永远不会失败,可能会导致循环出现问题。它还将覆盖
设置[显示]

请尝试下面的代码以查看是否存在差异

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;
}

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

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;
}
intmain()
{
整数计数=0;
显示设备温度={0};
温度cb=sizeof(显示设备);
while(EnumDisplayDevices(NULL、count和temp、EDD\u GET\u DEVICE\u INTERFACE\u NAME))
计数++;
DEVMODE*settings=malloc(count*sizeof(DEVMODE));
DISPLAY_DEVICE*devices=malloc(count*sizeof(DISPLAY_DEVICE));
for(int index=0;index
问题与windows API无关,也与强制转换无关。铸造是不需要的,所以我删除了它。
这是由于错误使用代码中的变量造成的。正如我所说,我只需要每个显示器的当前分辨率以及
设备
设置
结构的每个索引,我只需要与活动显示器相关的数据。这是通过使用
显示
变量来确保的,该变量仅在设备具有可读设置时递增。相反地,
索引
变量应向每个循环递增,直到
枚举显示设备A
失败

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

这是正确的代码:

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;
    }

您是否尝试过使用
if(result!=0)
而不是
if(result==1)
?根据文档,结果不是0对1,失败时为0,成功时为非零。此外,
result
必须在主
for
循环之前正确初始化,您确定要初始化它吗?(更好的是,跳过主
for
循环?)硬件问题中的条件检查。这是一种笔记本电脑,可以让您选择要使用主LCD面板上的驱动器的适配器。作为一种节省电池的功能,非活动的适配器会物理断电。@MikeNakis我明白你的意思,但建议的更改并不能解决问题。调试代码时,我看到EnumDisplaySettingsA在while循环中返回0(模式为
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;
}
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;
    }