首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在多个监视器中正确使用SetDisplayConfig?

如何在多个监视器中正确使用SetDisplayConfig?
EN

Stack Overflow用户
提问于 2019-07-21 20:10:58
回答 1查看 2.3K关注 0票数 1

我正在创建一个小程序,它将包括所有桌面显示(扩展模式)或禁用所有辅助显示(显示可以连接到gpus和集成图形)。

这个程序是为Windows7编写的,所以我依赖于互联网上的信息,决定使用SetDisplayConfig API,但是()函数出现了一个问题。例如,这段关闭所有辅助显示的代码工作得很好,因为'i‘递增了一个显示:

代码语言:javascript
运行
复制
    UINT32 PathCount = 0;  //path count
    UINT32 ModeCount = 0;  //mode count
    HRESULT hr;
    hr = GetDisplayConfigBufferSizes(QDC_ALL_PATHS, &PathCount, &ModeCount);
    std::vector<DISPLAYCONFIG_PATH_INFO> pathArray(PathCount);
    std::vector<DISPLAYCONFIG_MODE_INFO> modeArray(ModeCount);
    hr = QueryDisplayConfig(QDC_ALL_PATHS, &PathCount, &pathArray[0], &ModeCount, &modeArray[0], NULL);

    for (int i = 1; i < PathCount;i++)
    {
        if(pathArray[i].flags != 0)
        {
            pathArray[i].flags = 0;
            hr = SetDisplayConfig(PathCount, &pathArray[0], ModeCount, &modeArray[0], SDC_APPLY | SDC_USE_SUPPLIED_DISPLAY_CONFIG | SDC_ALLOW_CHANGES);
        }
    }

为了扩展显示,我找到了以下代码:

代码语言:javascript
运行
复制
SetDisplayConfig(0, NULL, 0, NULL, SDC_TOPOLOGY_EXTEND | SDC_APPLY);

这个函数具有这个特定的参数,但它只针对我的第二个显示器,它是作为我的主显示器与gpu相连的,而不是第三个与主板相连的显示器(只有在我从gpu中断掉第二个显示器后,这个功能才能与主板相连的显示器一起工作)。

我试着用

代码语言:javascript
运行
复制
    for (int i = 1; i < PathCount;i++)
    {
        if(pathArray[i].flags != 1)
        {
            pathArray[i].flags = 1;
            hr = SetDisplayConfig(PathCount, &pathArray[0], ModeCount, &modeArray[0], SDC_TOPOLOGY_EXTEND | SDC_APPLY | SDC_PATH_PERSIST_IF_REQUIRED);
        }
    }

但接收ERROR_ADAP_HDW_ERR错误

所以我请求帮助我。如何使用带有“SetDisplayConfig”标志的SDC_TOPOLOGY_EXTEND()功能将特定的显示(或所有显示同时)作为目标,或者有另一种解决此问题的方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-27 08:42:33

所以我做了它,它不工作一些外来的显示设置(如多个usb显示器),但它可以工作,所有的显示器被添加到桌面(或桌面是分散到所有显示器)。

我是怎么做到的?微软绕道帮助我,通过监视windows 10中的哪些系统设置,当我将显示器添加到桌面时,它只是将最重要的属性设置为默认值。评论部分只在win 10上工作。

代码语言:javascript
运行
复制
HRESULT hr = S_OK;
    UINT32 NumPathArrayElements = 0;
    UINT32 NumModeInfoArrayElements = 0;
    //LONG error = GetDisplayConfigBufferSizes((QDC_ALL_PATHS | QDC_VIRTUAL_MODE_AWARE), &NumPathArrayElements, &NumModeInfoArrayElements);
    hr = GetDisplayConfigBufferSizes((QDC_ALL_PATHS), &NumPathArrayElements, &NumModeInfoArrayElements);
    std::vector<DISPLAYCONFIG_PATH_INFO> PathInfoArray2(NumPathArrayElements);
    std::vector<DISPLAYCONFIG_MODE_INFO> ModeInfoArray2(NumModeInfoArrayElements);
    //error = QueryDisplayConfig((QDC_ALL_PATHS | QDC_VIRTUAL_MODE_AWARE), &NumPathArrayElements, &PathInfoArray2[0], &NumModeInfoArrayElements, &ModeInfoArray2[0], NULL);
    hr = QueryDisplayConfig((QDC_ALL_PATHS), &NumPathArrayElements, &PathInfoArray2[0], &NumModeInfoArrayElements, &ModeInfoArray2[0], NULL);

    struct displaySourcePair
    {
        std::wstring displayName;
        UINT32 displayId;
    };

    std::vector<displaySourcePair> ocupiedDisplays;

    if (hr == S_OK)
    {

        DISPLAYCONFIG_SOURCE_DEVICE_NAME SourceName = {};
        SourceName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME;
        SourceName.header.size = sizeof(SourceName);

        DISPLAYCONFIG_TARGET_PREFERRED_MODE PreferedMode = {};
        PreferedMode.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE;
        PreferedMode.header.size = sizeof(PreferedMode);


        int newId = 0;


        for (UINT32 i = 0; i < NumPathArrayElements; i++)
        {
            bool match = false;
            SourceName.header.adapterId = PathInfoArray2[i].sourceInfo.adapterId;
            SourceName.header.id = PathInfoArray2[i].sourceInfo.id;

            PreferedMode.header.adapterId = PathInfoArray2[i].targetInfo.adapterId;
            PreferedMode.header.id = PathInfoArray2[i].targetInfo.id;

            hr = HRESULT_FROM_WIN32(DisplayConfigGetDeviceInfo(&SourceName.header));
            hr = HRESULT_FROM_WIN32(DisplayConfigGetDeviceInfo(&PreferedMode.header));

            if (hr == S_OK)
            {

                if ((PathInfoArray2[i].flags & DISPLAYCONFIG_PATH_ACTIVE) == true)
                {
                    std::wstring str = std::wstring(SourceName.viewGdiDeviceName);
                    displaySourcePair tmpStruct;
                    tmpStruct.displayId = PreferedMode.header.id;
                    tmpStruct.displayName = str;
                    ocupiedDisplays.push_back(tmpStruct);
                }

                for (int k = 0; k < ocupiedDisplays.size(); k++)
                {
                    std::wstring str = std::wstring(SourceName.viewGdiDeviceName);
                    if (ocupiedDisplays[k].displayName == str || ocupiedDisplays[k].displayId == PreferedMode.header.id)
                    {
                        match = true;
                    }
                }

                if (match == false && PathInfoArray2[i].targetInfo.targetAvailable == 1)
                {
                    PathInfoArray2[i].flags |= DISPLAYCONFIG_PATH_ACTIVE;
                    std::wstring str = std::wstring(SourceName.viewGdiDeviceName);
                    displaySourcePair tmpStruct;
                    tmpStruct.displayId = PreferedMode.header.id;
                    tmpStruct.displayName = str;
                    ocupiedDisplays.push_back(tmpStruct);
                }

                if (PathInfoArray2[i].targetInfo.targetAvailable == 1)
                {
                    PathInfoArray2[i].sourceInfo.id = newId;
                    newId++;
                }

                if (PathInfoArray2[i].targetInfo.id != PreferedMode.header.id)
                {
                    PathInfoArray2[i].targetInfo.id = PreferedMode.header.id;
                }

                PathInfoArray2[i].sourceInfo.modeInfoIdx = DISPLAYCONFIG_PATH_MODE_IDX_INVALID;
                PathInfoArray2[i].targetInfo.modeInfoIdx = DISPLAYCONFIG_PATH_MODE_IDX_INVALID;
            }
        }

        //hr = SetDisplayConfig(NumPathArrayElements, &PathInfoArray2[0], 0, NULL, (SDC_VALIDATE | SDC_TOPOLOGY_SUPPLIED | SDC_ALLOW_PATH_ORDER_CHANGES | SDC_VIRTUAL_MODE_AWARE));
        //hr = SetDisplayConfig(NumPathArrayElements, &PathInfoArray2[0], 0, NULL, (SDC_APPLY | SDC_TOPOLOGY_SUPPLIED | SDC_ALLOW_PATH_ORDER_CHANGES | SDC_VIRTUAL_MODE_AWARE));
        hr = SetDisplayConfig(NumPathArrayElements, &PathInfoArray2[0], 0, NULL, (SDC_VALIDATE | SDC_TOPOLOGY_SUPPLIED | SDC_ALLOW_PATH_ORDER_CHANGES));
        hr = SetDisplayConfig(NumPathArrayElements, &PathInfoArray2[0], 0, NULL, (SDC_APPLY | SDC_TOPOLOGY_SUPPLIED | SDC_ALLOW_PATH_ORDER_CHANGES));
    }
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57136638

复制
相关文章

相似问题

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