Can';无法使用EnumDisplaySettings获取所有设备的显示分辨率
我需要获取连接到计算机的所有监视器的当前显示分辨率 我可以使用EnumDisplayDevicesAAPI成功枚举显示设备,但由于未知原因,我无法使用EnumDisplayDevicesAAPI获取设备的当前显示分辨率。\DISPLAY2。 代码如下: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
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;
}