如何在多个显示器上正确使用 SetDisplayConfig?

2024-03-19

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

该程序适用于Windows 7,因此根据互联网上的信息,我决定使用CCD API,但遇到了SetDisplayConfig()函数的问题。 例如,关闭所有辅助显示器的代码可以完美运行,因为“i”递增其中一个显示器将关闭:

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

为了扩展显示,我找到了这段代码:

SetDisplayConfig(0, NULL, 0, NULL, SDC_TOPOLOGY_EXTEND | SDC_APPLY);

具有此特定参数的此功能有效,但它仅针对连接到 GPU 作为主显示器的第二个显示器,而不是连接到主板的第三个显示器(仅在我以物理方式断开第二个显示器与 GPU 的连接后,此功能才有效)显示器连接到主板)。

我尝试使用

    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 错误

所以我请求帮助我。如何使用带有“SDC_TOPOLOGY_EXTEND”标志的 SetDisplayConfig() 函数来定位特定显示器(或一次所有显示器),或者还有另一种方法来解决此问题?


所以我做到了,它不适用于一些奇特的显示设置(如多个 USB 显示器),但它可以工作,并且所有显示器都添加到桌面(或桌面拉伸到所有显示器)

我是怎么做到的? Microsoft detours 帮助了我,通过监视 Windows 10 中的系统设置在我将显示添加到桌面时执行的操作,它只是将最重要的属性设置为默认值。 注释部分仅适用于 win 10。

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));
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在多个显示器上正确使用 SetDisplayConfig? 的相关文章

  • 将集合绑定到自定义控件属性

    我没有运气尝试将数据集合绑定到我的自定义控件的属性 我已经实现了该控件的字符串属性的机制 在此处提供了一些帮助 并期望集合类型同样简单 但是我无法让它再次工作 这是我的自定义控件视图
  • 在 C/C++ 中获得正模数的最快方法

    通常在我的内部循环中 我需要以 环绕 方式索引数组 因此 例如 如果数组大小为 100 并且我的代码要求元素 2 则应该给它元素 98 高级语言 例如 Python 可以简单地使用my array index array size 但由于某
  • 有没有快速创建集合的方法?

    目前我正在创建一个像这样的新集 std set a s s insert a1 s insert a2 s insert a3 s insert a10 有没有办法创建s在一行 int myints 10 20 30 40 50 std s
  • 在 C# 中按元素相乘数组具有意想不到的性能

    我想找到按元素相乘两个数组的最佳方法 这是更广泛项目的一部分 其中性能而不是唯一的考虑因素 我今天开始用 C Linqpad 编写一些函数 因此它还没有以任何方式进行优化 下面代码的输出如下 Environment ProcessorCou
  • 更改 Qt OpenGL 窗口示例以使用 OpenGL 3.3

    我正在尝试更改 Qt OpenGL 示例以使用更现代的 opengl 版本 330 似乎合适 所以我做了 在 main cpp 上设置版本和配置文件 设置着色器版本 更改着色器以使用统一 它现在构建没有任何错误 但我只看到一个空白窗口 我错
  • 我如何在 C# .NET(win7 手机)中使用“DataContractJsonSerializer”读入“嵌套”Json 文件?

    我有一个问题 如果我的 json 文件看起来像这样 Numbers 45387 Words 空间桶 我可以很好地阅读它 但是如果它看起来像这样 Main Numbers 45387 Words 空间桶 某事 数字 12345 单词 克兰斯基
  • 类特定的新删除运算符是否必须声明为静态

    标准中是否要求类特定的 new new delete 和 delete 是静态的 我可以让它们成为非静态成员运算符吗 为什么需要它们是静态的 它们被隐式声明为静态 即使您没有键入 static
  • ASP.Net Core 内容配置附件/内联

    我正在从 WebAPI 控制器返回一个文件 Content Disposition 标头值自动设置为 附件 例如 处置 附件 文件名 30956 pdf 文件名 UTF 8 30956 pdf 当它设置为附件时 浏览器将要求保存文件而不是打
  • fprintf() 线程安全吗?

    我正在为野人就餐问题的某些变量编写一个 C 解决方案 现在 我创建线程 每个线程都将 FILE 获取到同一个调试文件 在线程内我正在使用 fprintf 进行一些打印 打印的语句不受任何类型的互斥锁等保护 我没有在调试文件中观察到任何交错行
  • 类的成员复制

    在学习 复制成员 概念时 书中给出了如下说法 此外 如果非静态成员是引用 const 或没有复制赋值的用户定义类型 则无法生成默认赋值 我不太明白这个声明到底想传达什么 或者说这个说法指的是哪一种场景 谢谢 该语句与编译器自动为您编写的类
  • 单例模式和 std::unique_ptr

    std unique ptr唯一地控制它指向的对象 因此不使用引用计数 单例确保利用引用计数只能创建一个对象 那么会std unique ptr与单例执行相同 单例确保只有一个实例属于一种类型 A unique ptr确保只有一个智能指针到
  • 在 JSQMessagesViewController 中显示 LocationMediaItem

    我刚刚尝试实施LocationMediaItem in my Xamarin iOS应用程序使用JSQMessagesViewController 一切都很顺利 唯一的问题是UICollectionView应该显示位置的单元格永远停留在加载
  • 为什么 set_symmetry_difference 无法与比较器一起使用?

    Example program include
  • 如何在标准 WPF ListView 中启用 UI 虚拟化

    我正在使用 NET 4 5 VS2012 并且我有一个 ListView 看起来像这样
  • 无法在内存位置找到异常源:cudaError_enum

    我正在尝试确定 Microsoft C 异常的来源 test fft exe 中 0x770ab9bc 处的第一次机会异常 Microsoft C 异常 内存位置 0x016cf234 处的 cudaError enum 我的构建环境是 I
  • .NET Core 中的跨平台文件名处理

    如何处理文件名System IO以跨平台方式运行类以使其在 Windows 和 Linux 上运行 例如 我编写的代码在 Windows 上完美运行 但它不会在 Ubuntu Linux 上创建文件 var tempFilename Dat
  • IEnumerable.Except 不起作用,那么我该怎么办?

    我有一个 linq to sql 数据库 非常简单 我们有 3 个表 项目和用户 有一个名为 User Projects 的连接表将它们连接在一起 我已经有了一个获得的工作方法IEnumberable
  • 跨多个域的 ASP.NET 会话

    是否有合适的 NET 解决方案来在多个域上提供持久服务器会话 即 如果该网站的用户在 www site1 com 下登录 他们也将在 www site2 com 下登录 安全是我们正在开发的程序的一个问题 Thanks 它是否需要在会话中
  • 使用taskkill停止Windows服务

    我需要帮助来使用 C 终止 Windows 服务 现在要终止该服务 请使用以下选项 从命令 sc queryex ServiceName 发现后PID服务的 taskkill pid 1234 exemple f 为了便于阅读 但如果您明白
  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁

随机推荐

  • 如何让文本区域自动扩展到最大高度?

    我正在学习CSS 我有一个包含灵活文本区域的 div 现在我希望当用户在textarea中输入多行内容时 textarea和外层div自动扩展高度 并且当textarea超过3行时 停止扩展并滚动textarea 我应该如何编写 CSS 渲
  • 在 JShell 上执行时相同语句的不同行为

    我正在研究一个问题来存储两个类的引用 例如 class A B b A B b this b b class B A a B A a this a a public static void main String s A a new A n
  • EF 6,代码第一个联结表名称

    我正在 EF 6 中尝试自定义命名约定 我有 2 个表和 1 个联结表 WebUser UserRequest WebUser UserRequest 我编写了应该能够重命名表的函数 从 WebUser 到 web user private
  • 无法在 Felix config.properties 中将 PAX-URL 的程序集协议与自动启动的捆绑包一起使用

    我正在尝试使用 PAX URL 这样我就可以即时组装未打包的捆绑包 如果我将 pax url assembly 1 2 1 jar 放入自动启动包中 然后键入 安装程序集 路径 到 我的 文件夹 一切正常 问题是 我想使用 gt felix
  • 如何在闪亮中创建登录页面?

    目标是拥有一个闪亮的模块ui1 R加载第二个模块ui2 R当按钮confirm被点击 我认为问题是is null input confirm 总是无效的 我需要的是仅使表达式无效一次confirm被点击 这个问题非常接近输入密码后启动Shi
  • 为什么我的温莎城堡控制器工厂的 GetControllerInstance() 被调用为空值?

    我正在使用温莎城堡来管理控制器实例 除其他外 我的控制器工厂如下所示 public class WindsorControllerFactory DefaultControllerFactory private WindsorContain
  • 在 iPhone 重启时启动 iOS BLE Central 应用程序

    我计划使用 CoreBluetooth 框架开发一个 iOS 应用程序 该应用程序可以连续监控计步器外围设备并计算脚步数 我知道 如果后台执行模式设置为 BLE Central 应用程序即使在后台也将继续接收 BLE 事件 Apple 文档
  • SQL存储过程检查表中的值是/否并执行sql

    检查table1中value是否 Y 然后立即执行sql select if select value1 from table1 where value desc Indicator and value1 Y then execute im
  • Elasticsearch 连接超时

    from datetime import datetime from elasticsearch import Elasticsearch es Elasticsearch doc author kimchy text Elasticsea
  • 如何从 TinyDB 数据库中检索单个值?

    我正在学习如何在 Python 上使用 TinyDB 并且我已经掌握了基础知识 添加 删除 更新等 但现在我正在尝试从数据库中检索特定值 我正在使用的代码在这个方法中 def showpassword show userdb get whe
  • 在 Go 中模拟 HTTPS 响应

    我正在尝试为向 Web 服务发出请求的包编写测试 我遇到问题可能是由于我对 TLS 缺乏了解 目前我的测试看起来像这样 func TestSimple server httptest NewServer http HandlerFunc f
  • 原则 2 中的动态表/实体名称

    我希望有人能够阐明我的代码发生了什么 我需要一个实体来表示通用表 作为具有 X id 后缀的表的模型 例如 我有一个实体 CustomerX 我需要查询的表是 cusotmer 1 customer 2 customer 3 等 我目前正在
  • select unique * 查询有多贵

    在sql server 2012中 我有一个包含超过2500万行且有重复项的表 该表没有唯一索引 它只有一个非聚集索引 我想消除重复项 所以我想到了以下内容 select distinct into temp table from prim
  • Angular CLI 在 ng 服务上偶尔会冻结计算机

    我有问题ng serve 当我在我的 Angular 项目上运行它时 大约 10 的时间 它会在此过程中冻结 并且整个计算机也会冻结 有时它会在一段时间 从20秒到120秒 后解冻并成功编译 有时我需要手动关闭计算机电源 我已经在 2 台计
  • 在 CSS 中应该使用 rgba(0, 0, 0, 0) 还是 rgba(255, 255, 255, 0) 来实现透明度?

    你应该使用rgba 0 0 0 0 or rgba 255 255 255 0 CSS 的透明度 各自的优点和缺点是什么 最后一个参数为rgba 函数是 alpha 或 opacity 参数 如果您将其设置为0它将意味着 完全透明 前三个参
  • 将datagridview导出到word文档c#

    我正在尝试将数据网格导出到Word文档 但不是这个结果 EmployeeID EmployeeName Birth Phone Address DateOfHiring Salary EmloyeeType 1 name 1 11 test
  • Mandrill 通过 Laravel / PHP 入站电子邮件

    我想知道是否有人可以帮助我解决我在研究 Laravel 和通过 Mandrill 入站电子邮件处理相关问题时遇到的一些问题 基本上我希望能够通过 Mandrill 接收电子邮件并将它们存储在我的 Laravel 数据库中 现在我不确定我是否
  • 将闪亮的小部件显示与特定的导航栏 tabPanel() 选择连接起来

    我有一个闪亮的仪表板 其中有一个导航栏页面 其中包含两个 tabPanel Summary and Available Funds Then Available Funds 由一个tabsetPanel 有两个选项卡面板 Plot and
  • Android蓝牙UUID连接APP到ANDROID

    我正在构建一个 Android 应用程序 用于跟踪设备上的蓝牙连接 并在超出范围时触发警报 Android 文档要求提供 UUID 才能建立连接 uuid 是用于唯一标识信息的字符串 ID 的通用唯一标识符 UUID 标准化 128 位格式
  • 如何在多个显示器上正确使用 SetDisplayConfig?

    我正在创建一个小程序 它将包含桌面中的所有显示器 扩展模式 或禁用所有辅助显示器 显示器可以连接到 GPU 和集成显卡 该程序适用于Windows 7 因此根据互联网上的信息 我决定使用CCD API 但遇到了SetDisplayConfi