开发者

How do I get the number of displays in windows?

开发者 https://www.devze.com 2023-04-12 20:03 出处:网络
I want to count the number of active displays. For Mac I can use the following: CGDisplayCount nDisplays;

I want to count the number of active displays. For Mac I can use the following:

CGDisplayCount nDisplays;
CGG开发者_Go百科etActiveDisplayList(0,0, &nDisplays);
log.printf("Displays connected: %d",(int)nDisplays);

How can I achieve the same in Windows? I've found EnumDisplayMonitors but I can't work out how to use it.


As you have discovered, EnumDisplayMonitors() will do the job but it is a little tricky to call. The documentation states:

The EnumDisplayMonitors function enumerates display monitors (including invisible pseudo-monitors associated with the mirroring drivers) that intersect a region formed by the intersection of a specified clipping rectangle and the visible region of a device context. EnumDisplayMonitors calls an application-defined MonitorEnumProc callback function once for each monitor that is enumerated. Note that GetSystemMetrics (SM_CMONITORS) counts only the display monitors.

This leads us to an easier solution: GetSystemMetrics(SM_CMONITORS). Indeed this may be even better than EnumDisplayMonitors() if you have psuedo-monitors.


As illustration of calling EnumDisplayMonitors() try this:

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
}


Not tested, but essentially you only need to provide the callback for the enum function:

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


The problem with above approaches is that they do not detect the correct number of monitors in Clone, Internal, External topologies. They get the correct number only in Extended topology. There is a way to get the correct number of monitors in any topology with QueryDisplayConfig function. You have to use QDC_ALL_PATHS in flags and count only unique monitors found.

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

Use DisplayConfigGetDeviceInfo to get the monitor name from the path target.

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

You will get the monitor name in:

targetName.monitorDevicePath, targetName.monitorFriendlyDeviceName
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号