QueryDisplayConfig 函数 (winuser.h)

QueryDisplayConfig 函数检索有关当前设置中所有显示设备或视图的所有可能显示路径的信息。

语法

LONG QueryDisplayConfig(
  [in]            UINT32                    flags,
  [in, out]       UINT32                    *numPathArrayElements,
  [out]           DISPLAYCONFIG_PATH_INFO   *pathArray,
  [in, out]       UINT32                    *numModeInfoArrayElements,
  [out]           DISPLAYCONFIG_MODE_INFO   *modeInfoArray,
  [out, optional] DISPLAYCONFIG_TOPOLOGY_ID *currentTopologyId
);

参数

[in] flags

要检索的信息的类型。 Flags 参数的值必须使用以下值之一。

含义
QDC_ALL_PATHS
0x00000001
返回源到目标的所有可能路径组合。

注意

对于任何临时模式,QDC_ALL_PATHS设置意味着返回的模式数据可能与存储在持久性数据库中的模式数据不同。

注意

此标志的计算成本可能很高。 除非调用方尝试确定源和目标之间的有效连接集,否则不建议使用此标志。

QDC_ONLY_ACTIVE_PATHS
0x00000002
仅返回当前活动路径。

注意

对于任何临时模式,QDC_ONLY_ACTIVE_PATHS设置意味着返回的模式数据可能与存储在持久性数据库中的模式数据不同。

QDC_DATABASE_CURRENT
0x00000004
返回当前连接的显示器的 CCD 数据库中定义的活动路径。

Flags 参数也可以是按位 OR,其中包含零个或多个以下值。

含义
QDC_VIRTUAL_MODE_AWARE
0x00000010
此标志应与其他标志一起按位 OR,以指示调用方知道虚拟模式支持。

支持从 Windows 10 开始。

QDC_INCLUDE_HMD
0x00000020
此标志应按位 OR 与QDC_ONLY_ACTIVE_PATHS,以指示调用方希望将头戴式显示器 (HMD) 包含在活动路径列表中。 有关更多信息,请参见备注。

从 Windows 10 1703 创意者更新开始支持。

QDC_VIRTUAL_REFRESH_RATE_AWARE
0x00000040
此标志应与其他标志一起按位 OR,以指示调用方知道虚拟刷新率支持。

从 Windows 11 开始支持。

[in, out] numPathArrayElements

指向包含 pPathInfoArray 中元素数的变量的指针。 此参数不能为 NULL。 如果 QueryDisplayConfig 返回ERROR_SUCCESS, 则 pNumPathInfoElements 将更新为 pPathInfoArray 中的有效条目数。

[out] pathArray

指向包含 DISPLAYCONFIG_PATH_INFO 元素数组的变量的指针。 pPathInfoArray 中的每个元素描述从源到目标的单个路径。 源和目标模式信息索引仅与同时为 API 返回的 pmodeInfoArray 表组合使用。 此参数不能为 NULLpPathInfoArray 始终按路径优先级顺序返回。 有关路径优先级顺序的详细信息,请参阅 路径优先级顺序

[in, out] numModeInfoArrayElements

指向变量的指针,该变量指定模式信息表元素中的数字。 此参数不能为 NULL。 如果 QueryDisplayConfig 返回ERROR_SUCCESS, 则 pNumModeInfoArrayElements 将更新为 pModeInfoArray 中的有效条目数。

[out] modeInfoArray

指向包含 DISPLAYCONFIG_MODE_INFO 元素数组的变量的指针。 此参数不能为 NULL

[out, optional] currentTopologyId

指向一个变量的指针,该变量接收 CCD 数据库中当前活动拓扑的标识符。 有关可能值的列表,请参阅 DISPLAYCONFIG_TOPOLOGY_ID 枚举类型。

仅当 Flags 参数值QDC_DATABASE_CURRENT时才设置 pCurrentTopologyId 参数。

如果将 Flags 参数值设置为 QDC_DATABASE_CURRENT, 则 pCurrentTopologyId 参数不得为 NULL。 如果未将 Flags 参数值设置为 QDC_DATABASE_CURRENT, 则 pCurrentTopologyId 参数值必须为 NULL

返回值

函数返回以下返回代码之一。

返回代码 说明
ERROR_SUCCESS
函数成功。
ERROR_INVALID_PARAMETER
指定的参数和标志的组合无效。
ERROR_NOT_SUPPORTED
系统未运行根据 Windows 显示驱动程序模型 (WDDM) 编写的图形驱动程序。 仅在运行 WDDM 驱动程序的系统上支持函数。
ERROR_ACCESS_DENIED
调用方无权访问控制台会话。 如果调用进程无权访问当前桌面或在远程会话上运行,则会发生此错误。
ERROR_GEN_FAILURE
发生了未指定的错误。
ERROR_INSUFFICIENT_BUFFER
提供的路径和模式缓冲区太小。

备注

由于 GetDisplayConfigBufferSizes 函数只能在特定时刻确定所需的数组大小,因此在调用 GetDisplayConfigBufferSizesQueryDisplayConfig 之间,系统配置可能会更改,并且提供的数组大小将不再足以存储新路径数据。 在这种情况下, QueryDisplayConfig 失败并ERROR_INSUFFICIENT_BUFFER,调用方应再次调用 GetDisplayConfigBufferSizes 以获取新的数组大小。 然后,调用方应分配正确的内存量。

QueryDisplayConfig 返回 pPathInfoArray 参数指定的路径数组中的路径,以及 pModeInfoArray 参数指定的模式数组中的源和目标模式。 QueryDisplayConfig 始终按路径优先级顺序返回路径。 如果在 Flags 参数中设置了QDC_ALL_PATHS, QueryDisplayConfig 将返回活动路径之后的所有非活动路径。

完整路径、源模式和目标模式信息适用于所有活动路径。 源和目标的DISPLAYCONFIG_PATH_SOURCE_INFODISPLAYCONFIG_PATH_TARGET_INFO结构中的 ModeInfoIdx 成员是为这些活动路径设置的。 对于非活动路径,返回的源和目标模式信息不可用;因此,路径结构中的目标信息设置为默认值,并且源和目标模式索引被标记为无效。 对于数据库查询,如果当前连接监视器具有条目, 则 QueryDisplayConfig 返回完整路径、源模式和目标模式信息 (与活动路径) 相同。 但是,如果数据库没有条目, QueryDisplayConfig 仅返回路径信息,默认目标详细信息 (与非活动路径) 相同。

有关源和目标模式信息如何与路径信息相关的示例,请参阅 模式信息与路径信息的关系

调用方可以使用 DisplayConfigGetDeviceInfo 获取有关源或目标设备的其他信息,例如,监视器名称和监视器首选模式和源设备名称。

如果当前正在强制投影目标,则DISPLAYCONFIG_PATH_TARGET_INFO结构的 statusFlags 成员设置了DISPLAYCONFIG_TARGET_FORCED_XXX标志之一。

如果在 Flags 参数中设置了QDC_DATABASE_CURRENT标志, QueryDisplayConfig 将在 pCurrentTopologyId 参数指向的变量中返回活动数据库拓扑的拓扑标识符。 如果在 Flags 参数中设置了 QDC_ALL_PATHS 或 QDC_ONLY_ACTIVE_PATHS 标志,则必须将 pCurrentTopologyId 参数设置为 NULL;否则, QueryDisplayConfig 返回ERROR_INVALID_PARAMETER。

如果调用方调用 QueryDisplayConfig 并在 Flags 参数中设置了QDC_DATABASE_CURRENT标志, 则 QueryDisplayConfig 会将 在 DISPLAYCONFIG_VIDEO_SIGNAL_INFO 结构的 totalSize 成员中指定的 DISPLAYCONFIG_2DREGION 结构初始化为零,并且不会完成DISPLAYCONFIG_2DREGION。

Windows SDK 文档中介绍的 EnumDisplaySettings Win32 函数 (返回的 DEVMODE 结构) 包含与源模式和目标模式相关的信息。 但是, CCD API 显式分隔源和目标模式组件。

头戴式和专用监视器

QueryDisplayConfig 和许多其他 Win32 显示 API 对头戴式和专用监视器的感知有限,因为这些显示器不参与 Windows 桌面环境。 但是,在某些情况下,需要了解这些显示器 (的连接性,例如内容保护方案) 。 对于这些受限方案, (QDC_INCLUDE_HMD | QDC_ONLY_ACTIVE_PATHS) 可用于发现头戴式显示器的连接。 这些路径将在 DISPLAYCONFIG_PATH_TARGET_INFO.statusFlags 字段中标记DISPLAYCONFIG_TARGET_IS_HMD标志。 Windows 10 1703 创意者更新中添加了此支持。

DPI 虚拟化

此 API 不参与 DPI 虚拟化。 DEVMODE 结构中的所有大小都以物理像素为单位,与调用上下文无关。

示例

以下示例使用 QueryDisplayConfigGetDisplayConfigBufferSize 枚举活动显示路径,并使用 DisplayConfigGetDeviceInfo 输出每个路径的数据。

#include <windows.h>
#include <vector>
#include <iostream>
#include <string>

using namespace std;

int main()
{
    vector<DISPLAYCONFIG_PATH_INFO> paths;
    vector<DISPLAYCONFIG_MODE_INFO> modes;
    UINT32 flags = QDC_ONLY_ACTIVE_PATHS | QDC_VIRTUAL_MODE_AWARE;
    LONG result = ERROR_SUCCESS;

    do
    {
        // Determine how many path and mode structures to allocate
        UINT32 pathCount, modeCount;
        result = GetDisplayConfigBufferSizes(flags, &pathCount, &modeCount);

        if (result != ERROR_SUCCESS)
        {
            return HRESULT_FROM_WIN32(result);
        }

        // Allocate the path and mode arrays
        paths.resize(pathCount);
        modes.resize(modeCount);

        // Get all active paths and their modes
        result = QueryDisplayConfig(flags, &pathCount, paths.data(), &modeCount, modes.data(), nullptr);

        // The function may have returned fewer paths/modes than estimated
        paths.resize(pathCount);
        modes.resize(modeCount);

        // It's possible that between the call to GetDisplayConfigBufferSizes and QueryDisplayConfig
        // that the display state changed, so loop on the case of ERROR_INSUFFICIENT_BUFFER.
    } while (result == ERROR_INSUFFICIENT_BUFFER);

    if (result != ERROR_SUCCESS)
    {
        return HRESULT_FROM_WIN32(result);
    }

    // For each active path
    for (auto& path : paths)
    {
        // Find the target (monitor) friendly name
        DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = {};
        targetName.header.adapterId = path.targetInfo.adapterId;
        targetName.header.id = path.targetInfo.id;
        targetName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME;
        targetName.header.size = sizeof(targetName);
        result = DisplayConfigGetDeviceInfo(&targetName.header);

        if (result != ERROR_SUCCESS)
        {
            return HRESULT_FROM_WIN32(result);
        }

        // Find the adapter device name
        DISPLAYCONFIG_ADAPTER_NAME adapterName = {};
        adapterName.header.adapterId = path.targetInfo.adapterId;
        adapterName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME;
        adapterName.header.size = sizeof(adapterName);

        result = DisplayConfigGetDeviceInfo(&adapterName.header);

        if (result != ERROR_SUCCESS)
        {
            return HRESULT_FROM_WIN32(result);
        }

        wcout
            << L"Monitor with name "
            << (targetName.flags.friendlyNameFromEdid ? targetName.monitorFriendlyDeviceName : L"Unknown")
            << L" is connected to adapter "
            << adapterName.adapterDevicePath
            << L" on target "
            << path.targetInfo.id
            << L"\n";
    }
}

要求

   
最低受支持的客户端 在 Windows 7 及更高版本的 Windows 操作系统中可用。
目标平台 通用
标头 winuser.h (包括 Windows.h)
Library User32.lib;Windows 10 上的 OneCoreUAP.lib
DLL User32.dll
API 集 ext-ms-win-ntuser-sysparams-ext-l1-1-1 (在 Windows 10 版本 10.0.14393 中引入)

另请参阅

DISPLAYCONFIG_MODE_INFO

DISPLAYCONFIG_PATH_INFO

DISPLAYCONFIG_PATH_SOURCE_INFO

DISPLAYCONFIG_PATH_TARGET_INFO

DISPLAYCONFIG_TOPOLOGY_ID

DisplayConfigGetDeviceInfo

SetDisplayConfig