当前位置: 首页 > news >正文

Windows 图形显示驱动开发-WDDM 3.2-自动显示切换(十二)

API 更改

ADS 功能增加了以下公共 API 功能:

  1. 枚举系统中的多路复用器设备。
  2. 查询有关多路复用器的信息,例如,它连接了哪些目标,以及当前切换到哪个目标。
  3. 触发多路复用器切换。
  4. 如何检测多路复用器是否已切换。
枚举系统中的多路复用器设备

应用程序可以使用通用的即插即用 API 来查找代表正常显示多路复用器的设备接口。 用户模式组件可使用Windows.Devices.Enumeration.DeviceInformation。 无论是 C# 还是 C++,都可以使用这些 API 来枚举多路复用器设备。

// Display Mux device interface
// {93c33929-3180-46d3-8aab-008c84ad1e6e}
DEFINE_GUID(GUID_DEVINTERFACE_DISPLAYMUX, 0x93c33929, 0x3180, 0x46d3, 0x8a, 0xab, 0x00, 0x8c, 0x84, 0xad, 0x1e, 0x6e);
IDisplayMuxDevice 接口

添加 IDisplayMuxDevice 接口来表示多路复用器设备。

以下代码演示了如何使用 Windows Runtime API 枚举显示多路复用器设备、查询其状态、切换活动显示目标以及对状态变化做出反应。

#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Devices.Enumeration.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Devices.Display.Core.h>

#include <string>
#include <sstream>
#include <iomanip>
#include <windows.h>

namespace winrt
{
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Collections;
using namespace winrt::Windows::Devices::Enumeration;
using namespace winrt::Windows::Devices::Display;
using namespace winrt::Windows::Devices::Display::Core;
} // namespace winrt

void SwitchDisplayMuxTarget()
{
    // PnP device interface search string for Mux device interface
    std::wstring muxDeviceSelector = L"System.Devices.InterfaceClassGuid:=\"{93c33929-3180-46d3-8aab-008c84ad1e6e}\" AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True";

    // Execute the device interface query
    winrt::DeviceInformationCollection deviceInformations = winrt::DeviceInformation::FindAllAsync(muxDeviceSelector, nullptr).get();
    if (deviceInformations.Size() == 0)
    {
        printf("No DisplayMux devices\n");
        return;
    }
    printf("%ld display mux devices found\n\n", deviceInformations.Size());

    // Only one mux in first release but here is generic code for multiple
    for (unsigned int i = 0; i < deviceInformations.Size(); i++)
    {
        printf("Display Mux device %ld :\n", i);

        // Get the device interface so we can query the info
        winrt::DeviceInformation deviceInfo = deviceInformations.GetAt(i);

        // Get the device id
        std::wstring deviceId = deviceInfo.Id().c_str();
        printf("    Device ID string : %S \n", deviceId.c_str());

        // Create the DisplayMuxDevice object
        auto displayMuxDevice = winrt::DisplayMuxDevice::FromIdAsync(deviceId).get();
        if (!displayMuxDevice)
        {
            printf("Failed to create DisplayMuxDevice object");
            continue;
        }

        // Check if DisplayMux is active
        auto displayMuxActive = displayMuxDevice.IsActive();
        printf("    DisplayMux state : %s \n", displayMuxActive ? "Active" : "Inactive");
        if (!displayMuxActive)
        {
            continue;
        }

        // Register for call back when the state of the DisplayMux changes
        UINT changeCount = 0;
        auto token = displayMuxDevice.Changed([&changeCount](auto, auto Args) -> HRESULT {
            changeCount++;
            return S_OK;
        });

        // Find targets connected to the DisplayMux and the current target
        auto targetsList = displayMuxDevice.GetAvailableMuxTargets();
        winrt::DisplayTarget currentTarget = displayMuxDevice.CurrentTarget();

        // Switch the display mux to the other target
        // NOTE SetPreferredTarget() is a sync method so use .get() to wait for the operation to complete
        printf("\n");
        if (currentTarget == targetsList.GetAt(0))
        {
            printf("DisplayMux currently connected to first target\n");
            displayMuxDevice.SetPreferredTarget(targetsList.GetAt(1)).get();
            printf("Calling SetPreferredTarget to switch DisplayMux to second target\n");
        }
        else if (currentTarget == targetsList.GetAt(1))
        {
            printf("DisplayMux currently connected to second target\n");
            displayMuxDevice.SetPreferredTarget(targetsList.GetAt(0)).get();
            printf("Calling SetPreferredTarget to switch DisplayMux to first target\n");
        }
        else
        {
            printf("Could not find current target in target list\n");
        }

        // Now read the current position
        currentTarget = displayMuxDevice.CurrentTarget();
        targetsList = displayMuxDevice.GetAvailableMuxTargets();
        if (currentTarget == targetsList.GetAt(0))
        {
            printf("DisplayMux is now currently connected to first target\n");
        }
        else if (currentTarget == targetsList.GetAt(1))
        {
            printf("DisplayMux is now currently connected to second target\n");
        }
        else
        {
            printf("Could not find current target in target list\n");
        }

        // Now unregister for change callback and display the
        displayMuxDevice.Changed(token);
        printf("DisplayMux state change callback was called %ld times\n\n", changeCount);
    }
}

相关文章:

  • 民安智库:物业满意度调查的数据分析经验分享
  • 《宇宙》自我意识之局部宇宙,无垠星空之真实宇宙
  • Android+SpringBoot的老年人健康饮食小程序平台
  • 【react】快速上手基础教程
  • 《向华为学习:BEM战略解码》课程大纲
  • 消息队列学习-常用消息队列中间件的对比分析
  • 加载大数据时性能压力优化
  • phpstudy小皮面板下载安装及启动MySQL的报错解决
  • git 强推
  • python随机数如何赋值给变量
  • 信号和槽
  • 物联网智能项目实战:从概念到实现
  • 计算机组成与接口12
  • 蓝桥备赛(五)- string(下)
  • Java 连接 Redis 的两种方式
  • 1-4查找命令
  • 使用Docker方式一键部署MySQL和Redis数据库详解
  • KaiwuDB| Google Spanner 经典架构回顾
  • el-table修改表格颜色
  • 【MySQL】表的约束
  • 怎么做网站一张图/体验式营销
  • 企业网站建设框架图/seo品牌
  • 做h网站/网站的优化与推广分析
  • 企业手机网站建设市场分析/竞价推广账户竞价托管收费
  • 成都游戏网站开发/网络营销公司排行
  • 广西壮族自治区住房和建设厅网站/西安做网站的公司