我想要统计活动显示器的数量。对于Mac,我可以使用以下方法:
CGDisplayCount nDisplays;
CGGetActiveDisplayList(0,0, &nDisplays);
log.printf("Displays connected: %d",(int)nDisplays);
我该如何在Windows中实现相同的功能?我已经找到了EnumDisplayMonitors,但我不知道该如何使用它。
我想要统计活动显示器的数量。对于Mac,我可以使用以下方法:
CGDisplayCount nDisplays;
CGGetActiveDisplayList(0,0, &nDisplays);
log.printf("Displays connected: %d",(int)nDisplays);
我该如何在Windows中实现相同的功能?我已经找到了EnumDisplayMonitors,但我不知道该如何使用它。
正如您所发现的那样,EnumDisplayMonitors()
可以完成这项工作,但是调用它有点棘手。文档说明如下:
EnumDisplayMonitors 函数枚举显示器(包括与镜像驱动程序相关联的不可见伪显示器),这些显示器与指定剪辑矩形和设备上下文的可见区域的交集形成的区域相交。每枚举一个显示器,EnumDisplayMonitors 调用一次应用程序定义的 MonitorEnumProc 回调函数。请注意,GetSystemMetrics (SM_CMONITORS) 仅计算显示器。
这引导我们找到了一个更容易的解决方案:GetSystemMetrics(SM_CMONITORS)
。实际上,如果你有伪显示器,则这可能比EnumDisplayMonitors()
更好。
为了演示如何调用 EnumDisplayMonitors()
,请尝试以下操作:
BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
int *Count = (int*)dwData;
(*Count)++;
return TRUE;
}
int MonitorCount()
{
int Count = 0;
if (EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&Count))
return Count;
return -1;//signals an error
}
尚未经过测试,但基本上您只需要为枚举函数提供回调即可:
int numMonitors = 0;
BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
//lprcMonitor holds the rectangle that describes the monitor position and resolution)
numMonitors++;
return true;
}
int main()
{
EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, NULL);
}
DISPLAYCONFIG_TOPOLOGY_ID currTopologyId = 0;
UINT32 numPathArrayElements = 0;
UINT32 numModeInfoArrayElements = 0;
LONG retCode = ::GetDisplayConfigBufferSizes(flags, &numPathArrayElements, &numModeInfoArrayElements);
auto pathArray = std::make_unique<DISPLAYCONFIG_PATH_INFO[]>(numPathArrayElements);
auto modeInfoArray = std::make_unique<DISPLAYCONFIG_MODE_INFO[]>(numModeInfoArrayElements);
retCode = ::QueryDisplayConfig(flags, &numPathArrayElements, pathArray.get(), &numModeInfoArrayElements, modeInfoArray.get(), &currTopologyId);
DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = {};
targetName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME;
targetName.header.size = sizeof(targetName);
targetName.header.adapterId = pathInfo.targetInfo.adapterId;
targetName.header.id = pathInfo.targetInfo.id;
LONG retCode = ::DisplayConfigGetDeviceInfo(&targetName.header);
targetName.monitorDevicePath, targetName.monitorFriendlyDeviceName