API 更改
ADS 功能增加了以下公共 API 功能:
- 枚举系统中的多路复用器设备。
- 查询有关多路复用器的信息,例如,它连接了哪些目标,以及当前切换到哪个目标。
- 触发多路复用器切换。
- 如何检测多路复用器是否已切换。
枚举系统中的多路复用器设备
应用程序可以使用通用的即插即用 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);
}
}