SetDisplayConfig 函数通过以独占方式在当前会话中启用指定路径来修改显示拓扑、源和目标模式。
LONG SetDisplayConfig(
[in] UINT32 numPathArrayElements,
[in, optional] DISPLAYCONFIG_PATH_INFO *pathArray,
[in] UINT32 numModeInfoArrayElements,
[in, optional] DISPLAYCONFIG_MODE_INFO *modeInfoArray,
[in] UINT32 flags
);
in numPathArrayElements
pathArray 中的元素数。
in, optional pathArray
要设置的所有显示路径的数组。仅设置此数组中在 DISPLAYCONFIG_PATH_INFO 的标志成员中设置了 DISPLAYCONFIG_PATH_ACTIVE 标志的路径。此参数可以为 NULL。活动路径在此数组中的显示顺序决定了路径优先级。
in numModeInfoArrayElements
modeInfoArray 中的元素数。
in, optional modeInfoArray
显示源和目标模式信息的数组(DISPLAYCONFIG_MODE_INFO),由 DISPLAYCONFIG_PATH_SOURCE_INFO 的 modeInfoIdx 成员以及 pathArray 中路径信息的 DISPLAYCONFIG_PATH_TARGET_INFO 元素引用。此参数可以为 NULL。
in flags
标志值的按位 OR,指示此函数的行为。此参数可以是下列值之一,也可以是以下值的组合:0 无效。
SDC_APPLY (0x00000080):设置生成的拓扑、源和目标模式。
SDC_NO_OPTIMIZATION (0x00000100):SDC_APPLY 标志的修饰符。这会导致更改模式一直强制到每个活动显示器的驱动程序。
SDC_USE_SUPPLIED_DISPLAY_CONFIG (0x00000020):使用 pathArray 和 modeInfoArray 参数中提供的拓扑、源和目标模式信息,而不是在数据库中查找配置。
SDC_SAVE_TO_DATABASE (0x00000200):生成的拓扑、源和目标模式将保存到数据库。
SDC_VALIDATE (0x00000040):系统测试请求的拓扑、源和目标模式信息,以确定是否可以设置它。
SDC_ALLOW_CHANGES (0x00000400):如果需要,该函数可以修改指定的源和目标模式信息,以创建功能显示路径集。
SDC_TOPOLOGY_CLONE (0x00000002):调用方从持久性数据库请求上次克隆配置。
SDC_TOPOLOGY_EXTEND (0x00000004):调用方从持久性数据库请求最后一个扩展配置。
SDC_TOPOLOGY_INTERNAL (0x00000001):调用方从持久性数据库请求最后一个内部配置。
SDC_TOPOLOGY_EXTERNAL (0x00000008):调用方从持久性数据库请求最后一个外部配置。
SDC_TOPOLOGY_SUPPLIED (0x00000010):调用方提供路径数据,因此函数仅查询持久性数据库以查找和使用源和目标模式。
SDC_USE_DATABASE_CURRENT (SDC_TOPOLOGY_INTERNAL | SDC_TOPOLOGY_CLONE | SDC_TOPOLOGY_EXTEND | SDC_TOPOLOGY_EXTERNAL):调用方请求所有四个 SDC_TOPOLOGY_XXX 配置的组合。此值通知 API 为当前连接的监视器设置最后一个已知显示配置。
SDC_PATH_PERSIST_IF_REQUIRED (0x00000800):当函数处理 SDC_TOPOLOGY_XXX 请求时,它可以强制目标上的路径持久性来满足该请求(如有必要)。有关此标志可以与之组合的其他标志的信息,请参阅下方列表。
SDC_FORCE_MODE_ENUMERATION (0x00001000):调用方请求为驱动程序提供更新 GDI 模式列表的机会,而 SetDisplayConfig 设置新的显示配置。仅当还指定了 SDC_USE_SUPPLIED_DISPLAY_CONFIG 和 SDC_APPLY 标志值时,此标志值才有效。
SDC_ALLOW_PATH_ORDER_CHANGES (0x00002000):SDC_TOPOLOGY_SUPPLIED 标志的修饰符,指示 SetDisplayConfig 在搜索数据库时应忽略所提供的拓扑的路径顺序。设置此标志时,拓扑集是包含所有路径的最新拓扑,而不考虑路径顺序。
SDC_VIRTUAL_MODE_AWARE (0x00008000):SDC_USE_SUPPLIED_DISPLAY_CONFIG 或 SDC_TOPOLOGY_SUPPLIED 的修饰符,指示调用方知道虚拟模式。从 Windows 10 开始支持。
SDC_VIRTUAL_REFRESH_RATE_AWARE (0x00020000):SDC_USE_SUPPLIED_DISPLAY_CONFIG 或 SDC_TOPOLOGY_SUPPLIED 的修饰符,指示调用方知道虚拟刷新率。从 Windows 11 开始支持。
以下列表包含 Flags 参数的值的有效组合:
-
- 必须设置 SDC_APPLY 或 SDC_VALIDATE,但不能同时设置两者。
-
- 必须设置 SDC_USE_SUPPLIED_DISPLAY_CONFIG 或 SDC_TOPOLOGY_XXX 的任意组合。不能使用任何 SDC_TOPOLOGY_XXX 标志设置 SDC_USE_SUPPLIED_DISPLAY_CONFIG。
-
- 只能使用 SDC_APPLY 设置 SDC_NO_OPTIMIZATION。
-
- 允许使用任何其他有效组合 SDC_ALLOW_CHANGES。
-
- 只能使用 SDC_USE_SUPPLIED_DISPLAY_CONFIG 设置 SDC_SAVE_TO_DATABASE。
-
- SDC_PATH_PERSIST_IF_REQUIRED 不能与 SDC_USE_SUPPLIED_DISPLAY_CONFIG 或 SDC_TOPOLOGY_SUPPLIED 一起使用。
-
- 仅当指定了 SDC_APPLY 和 SDC_USE_SUPPLIED_DISPLAY_CONFIG 时,SDC_FORCE_MODE_ENUMERATION 才有效。
-
- 仅当指定了 SDC_TOPOLOGY_SUPPLIED 时,才允许 SDC_ALLOW_PATH_ORDER_CHANGES。
-
- SDC_TOPOLOGY_SUPPLIED 不能与任何其他 SDC_TOPOLOGY_XXX 标志一起使用。由于验证问题,如果调用方违反此规则,SetDisplayConfig 不会失败。但是,SetDisplayConfig 会忽略 SDC_TOPOLOGY_SUPPLIED 标志。
-
- SDC_TOPOLOGY_XXX 标志可以组合使用。例如,如果设置了 SDC_TOPOLOGY_CLONE 和 SDC_TOPOLOGY_EXTEND,则 API 将使用最新的克隆或扩展拓扑,每个拓扑最近都为当前连接的监视器设置了该拓扑。
返回值
该函数返回以下返回代码之一。
- ERROR_SUCCESS:函数成功。
- ERROR_INVALID_PARAMETER:指定的参数和标志的组合无效。
- ERROR_NOT_SUPPORTED:系统未运行根据 Windows 显示驱动程序模型 (WDDM) 编写的图形驱动程序。仅在运行 WDDM 驱动程序的系统上支持该函数。
- ERROR_ACCESS_DENIED:调用方无权访问控制台会话。如果调用进程无权访问当前桌面或在远程会话上运行,则会发生此错误。
- ERROR_GEN_FAILURE:发生了未指定的错误。
- ERROR_BAD_CONFIGURATION:函数找不到调用方未指定的源模式和目标模式的可行解决方案。
注解
SetDisplayConfig 函数采用具有任何指定源和目标模式信息的活动显示路径,并使用最佳模式逻辑生成任何缺失的源和目标模式信息。然后,此函数设置完整的显示路径。
DISPLAYCONFIG_PATH_SOURCE_INFO 和 DISPLAYCONFIG_PATH_TARGET_INFO 结构中的 ModeInfoIdx 成员用于指示是否为给定的活动路径提供源模式和目标模式。如果任一项为 DISPLAYCONFIG_PATH_MODE_IDX_INVALID 索引值,则表示未指定模式信息。对于给定路径,指定路径加源模式或路径加源和目标模式信息是有效的。但是,在不使用源模式的情况下指定路径加目标模式是无效的。
每个源和目标标识符的源和目标模式只能在 modeInfoArray 数组中出现一次。例如,源标识符 S1 的源模式只能在表中出现一次;如果多个路径引用同一个源,则必须使用相同的 ModeInfoIdx。
预期大多数调用方使用 QueryDisplayConfig 获取当前配置以及其他有效可能性,然后使用 SetDisplayConfig 测试和设置配置。
活动路径在 PathArray 数组中的显示顺序决定了路径优先级。
默认情况下,SetDisplayConfig 永远不会更改提供的任何路径、源模式或目标模式信息。如果最佳模式逻辑在未更改指定的显示路径信息的情况下找不到解决方案,则 SetDisplayConfig 将失败并返回 ERROR_BAD_CONFIGURATION。在这种情况下,调用方应指定 SDC_ALLOW_CHANGES 标志,以允许函数调整某些指定的源和模式详细信息,以允许显示路径更改成功。
如果指定的或计算的源和目标模式具有相同的尺寸,SetDisplayConfig 会自动将路径缩放设置为 DISPLAYCONFIG_PPR_IDENTITY,然后再设置显示路径并将其保存在数据库中。有关 SetDisplayConfig 如何处理缩放的信息,请参阅"缩放桌面映像"。
当调用方指定 SDC_USE_SUPPLIED_DISPLAY_CONFIG 标志来设置克隆路径,并且路径数组中的任何源模式索引无效时,SetDisplayConfig 将确定该源中的所有源模式索引都无效。SetDisplayConfig 使用最佳模式逻辑来确定源模式信息。
除了 SDC_TOPOLOGY_SUPPLIED 标志(有关 SDC_TOPOLOGY_SUPPLIED 的详细信息,请参阅以下段落),SDC_TOPOLOGY_XXX 标志设置最后一个显示路径设置,包括该拓扑类型的源和目标模式信息。有关有效 SDC_TOPOLOGY_XXX 标志组合的信息,请参阅 Flags 参数说明。pathArray 和 modeInfoArray 参数必须为 NULL,并且其关联大小必须为零。例如,如果设置了 SDC_TOPOLOGY_CLONE 和 SDC_TOPOLOGY_EXTEND,则此函数使用最新的克隆或扩展显示路径配置。如果请求单个拓扑类型,则使用该类型的最后一个配置。如果以前从未设置过该拓扑,则 SetDisplayConfig 使用最佳拓扑逻辑查找最佳拓扑,然后使用最佳模式逻辑查找要使用的最佳源和目标模式。如果已设置拓扑标志的组合,并且其中没有数据库条目,则使用以下优先级:对于笔记本电脑:克隆、扩展、内部和外部;对于桌面:扩展优先,然后克隆。
调用方可以指定 SDC_TOPOLOGY_SUPPLIED 标志,以指示它仅设置(拓扑)和请求的路径信息,SetDisplayConfig 获取并使用持久性数据库中的源和目标模式信息。如果调用方提供的活动路径在持久性数据库中没有条目,SetDisplayConfig 将失败。在这种情况下,如果调用方再次使用相同的路径数据调用 SetDisplayConfig,但设置了 SDC_USE_SUPPLIED_DISPLAY_CONFIG 标志,则 SetDisplayConfig 将使用最佳模式逻辑来创建源和目标模式信息。当调用方指定 SDC_TOPOLOGY_SUPPLIED 时,调用方必须将 numModeInfoArrayElements 参数设置为零,将 modeInfoArray 参数设置为 NULL;但是,调用方必须为调用方所需的路径信息设置 pathArray 和 numPathArrayElements 参数。调用方必须将此路径数据中的所有源和目标模式索引标记为无效 (DISPLAYCONFIG_PATH_MODE_IDX_INVALID)。
下表提供了一些常见方案,其中调用 SetDisplayConfig 以及调用方传递给 Flags 参数以实现这些方案的标志组合。
方案:测试计算机上是否支持指定的显示配置
标志组合:SDC_VALIDATE | SDC_USE_SUPPLIED_DISPLAY_CONFIG
方案:设置指定的显示配置并保存到数据库
标志组合:SDC_APPLY | SDC_USE_SUPPLIED_DISPLAY_CONFIG | SDC_SAVE_TO_DATABASE
方案:设置临时显示配置(即不会保存显示配置)
标志组合:SDC_APPLY | SDC_USE_SUPPLIED_DISPLAY_CONFIG
方案:测试计算机上是否支持克隆
标志组合:SDC_VALIDATE | SDC_TOPOLOGY_CLONE
方案:设置克隆拓扑
标志组合:SDC_APPLY | SDC_TOPOLOGY_CLONE
方案:设置克隆拓扑并允许启用路径持久性(如果需要满足请求)
标志组合:SDC_APPLY | SDC_TOPOLOGY_CLONE | SDC_PATH_PERSIST_IF_REQUIRED
方案:从临时模式返回到上次保存的显示配置
标志组合:SDC_APPLY | SDC_USE_DATABASE_CURRENT
方案:仅给定路径信息,使用数据库中的路径的源和目标信息设置显示配置,并忽略路径顺序
标志组合:SDC_APPLY | SDC_TOPOLOGY_SUPPLIED | SDC_ALLOW_PATH_ORDER_CHANGES
DPI 虚拟化
此 API 不参与 DPI 虚拟化。DEVMODE 结构中的所有大小都以物理像素为单位,与调用上下文无关。