using System;
using System.Runtime.InteropServices;
using Vanara.Extensions;
using Vanara.InteropServices;
using static Vanara.PInvoke.Gdi32;
namespace Vanara.PInvoke
{
public static partial class User32_Gdi
{
/// The type of information to retrieve.
[PInvokeData("wingdi.h", MSDNShortId = "5ec7f521-28b5-4922-a3fc-aa4433de69e0")]
[Flags]
public enum QDC
{
/// The caller requests the table sizes to hold all the possible path combinations.
QDC_ALL_PATHS = 0x00000001,
/// The caller requests the table sizes to hold only active paths.
QDC_ONLY_ACTIVE_PATHS = 0x00000002,
///
/// The caller requests the table sizes to hold the active paths as defined in the persistence database for the currently
/// connected monitors.
///
QDC_DATABASE_CURRENT = 0x00000004,
/// Undocumented.
QDC_VIRTUAL_MODE_AWARE = 0x00000010,
/// Undocumented.
QDC_INCLUDE_HMD = 0x00000020,
}
/// Flag values that indicates the behavior of SetDisplayConfig.
[PInvokeData("wingdi.h", MSDNShortId = "9f649fa0-ffb2-44c6-9a66-049f888e3b04")]
[Flags]
public enum SDC
{
/// The caller requests the last internal configuration from the persistence database.
SDC_TOPOLOGY_INTERNAL = 0x00000001,
/// The caller requests the last clone configuration from the persistence database.
SDC_TOPOLOGY_CLONE = 0x00000002,
/// The caller requests the last extended configuration from the persistence database.
SDC_TOPOLOGY_EXTEND = 0x00000004,
/// The caller requests the last external configuration from the persistence database.
SDC_TOPOLOGY_EXTERNAL = 0x00000008,
///
/// The caller provides the path data so the function only queries the persistence database to find and use the source and target mode.
///
SDC_TOPOLOGY_SUPPLIED = 0x00000010,
///
/// The caller requests a combination of all four SDC_TOPOLOGY_XXX configurations. This value informs the API to set the last
/// known display configuration for the current connected monitors.
///
SDC_USE_DATABASE_CURRENT = SDC_TOPOLOGY_INTERNAL | SDC_TOPOLOGY_CLONE | SDC_TOPOLOGY_EXTEND | SDC_TOPOLOGY_EXTERNAL,
///
/// The topology, source, and target mode information that are supplied in the pathArray and the modeInfoArray parameters are
/// used, rather than looking up the configuration in the database.
///
SDC_USE_SUPPLIED_DISPLAY_CONFIG = 0x00000020,
///
/// The system tests for the requested topology, source, and target mode information to determine whether it can be set.
///
SDC_VALIDATE = 0x00000040,
/// The resulting topology, source, and target mode is set.
SDC_APPLY = 0x00000080,
///
/// A modifier to the SDC_APPLY flag. This causes the change mode to be forced all the way down to the driver for each active display.
///
SDC_NO_OPTIMIZATION = 0x00000100,
/// The resulting topology, source, and target mode are saved to the database.
SDC_SAVE_TO_DATABASE = 0x00000200,
///
/// If required, the function can modify the specified source and target mode information in order to create a functional display
/// path set.
///
SDC_ALLOW_CHANGES = 0x00000400,
///
/// When the function processes a SDC_TOPOLOGY_XXX request, it can force path persistence on a target to satisfy the request if
/// necessary. For information about the other flags that this flag can be combined with, see the following list.
///
SDC_PATH_PERSIST_IF_REQUIRED = 0x00000800,
///
/// The caller requests that the driver is given an opportunity to update the GDI mode list while SetDisplayConfig sets the new
/// display configuration. This flag value is only valid when the SDC_USE_SUPPLIED_DISPLAY_CONFIG and SDC_APPLY flag values are
/// also specified.
///
SDC_FORCE_MODE_ENUMERATION = 0x00001000,
///
/// A modifier to the SDC_TOPOLOGY_SUPPLIED flag that indicates that SetDisplayConfig should ignore the path order of the
/// supplied topology when searching the database. When this flag is set, the topology set is the most recent topology that
/// contains all the paths regardless of the path order.
///
SDC_ALLOW_PATH_ORDER_CHANGES = 0x00002000,
/// Undocumented.
SDC_VIRTUAL_MODE_AWARE = 0x00008000,
}
/// The DisplayConfigGetDeviceInfo function retrieves display configuration information about the device.
///
/// A pointer to a DISPLAYCONFIG_DEVICE_INFO_HEADER structure. This structure contains information about the request, which includes
/// the packet type in the type member. The type and size of additional data that DisplayConfigGetDeviceInfo returns
/// after the header structure depend on the packet type.
///
///
/// The function returns one of the following return codes.
///
///
/// Return code
/// Description
///
/// -
/// ERROR_SUCCESS
/// The function succeeded.
///
/// -
/// ERROR_INVALID_PARAMETER
/// The combination of parameters and flags specified are invalid.
///
/// -
/// ERROR_NOT_SUPPORTED
///
/// The system is not running a graphics driver that was written according to the Windows Display Driver Model (WDDM). The function
/// is only supported on a system with a WDDM driver running.
///
///
/// -
/// ERROR_ACCESS_DENIED
///
/// The caller does not have access to the console session. This error occurs if the calling process does not have access to the
/// current desktop or is running on a remote session.
///
///
/// -
/// ERROR_INSUFFICIENT_BUFFER
/// The size of the packet that the caller passes is not big enough for the information that the caller requests.
///
/// -
/// ERROR_GEN_FAILURE
/// An unspecified error occurred.
///
///
///
///
///
/// Use the DisplayConfigGetDeviceInfo function to obtain additional information about a source or target for an adapter, such
/// as the display name, the preferred display mode, and source device name.
///
///
/// The caller can call DisplayConfigGetDeviceInfo to obtain more friendly names to display in the user interface. The caller
/// can obtain names for the adapter, the source, and the target. The caller can also call DisplayConfigGetDeviceInfo to
/// obtain the best resolution of the connected display device.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-displayconfiggetdeviceinfo LONG
// DisplayConfigGetDeviceInfo( DISPLAYCONFIG_DEVICE_INFO_HEADER *requestPacket );
[DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winuser.h", MSDNShortId = "249dcb1a-4ce3-4478-8331-fb81e91313b0")]
public static extern Win32Error DisplayConfigGetDeviceInfo(IntPtr requestPacket);
/// The DisplayConfigGetDeviceInfo function retrieves display configuration information about the device.
/// The type of structure to return. This must match the type supported by .
///
/// A locally unique identifier (LUID) that identifies the adapter that the device information packet refers to.
///
///
/// The source or target identifier to get or set the device information for. The meaning of this identifier is related to the type
/// of information being requested. For example, in the case of DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME, this is the source identifier.
///
///
/// A DISPLAYCONFIG_DEVICE_INFO_TYPE enumerated value that determines the type of device information to retrieve or set. The
/// remainder of the packet for the retrieve or set operation follows immediately after the DISPLAYCONFIG_DEVICE_INFO_HEADER
/// structure. Leave this value as the default (0) to have the value inferred from .
///
/// The value of type for the information provided.
/// Request type does not match type param value.
public static T DisplayConfigGetDeviceInfo(ulong adapterId, uint id, DISPLAYCONFIG_DEVICE_INFO_TYPE type = 0) where T : struct
{
if (type == 0)
{
if (!CorrespondingTypeAttribute.CanGet(out type)) throw new ArgumentException("Unable to find enum value matching supplied type param.");
}
else if (!CorrespondingTypeAttribute.CanGet(type, typeof(T))) throw new ArgumentException("Request type does not match type param value.");
var hdr = new DISPLAYCONFIG_DEVICE_INFO_HEADER { size = (uint)Marshal.SizeOf(typeof(T)), type = type, adapterId = adapterId, id = id };
var mem = new SafeHGlobalHandle((int)hdr.size);
mem.Zero();
Marshal.StructureToPtr(hdr, (IntPtr)mem, false);
var hdr2 = mem.ToStructure();
var err = DisplayConfigGetDeviceInfo((IntPtr)mem);
err.ThrowIfFailed();
return mem.ToStructure();
}
/// The DisplayConfigSetDeviceInfo function sets the properties of a target.
///
/// A pointer to a DISPLAYCONFIG_DEVICE_INFO_HEADER structure that contains information to set for the device. The type and size of
/// additional data that DisplayConfigSetDeviceInfo uses for the configuration comes after the header structure. This
/// additional data depends on the packet type, as specified by the type member of DISPLAYCONFIG_DEVICE_INFO_HEADER. For
/// example, if the caller wants to change the boot persistence, that caller allocates and fills a
/// DISPLAYCONFIG_SET_TARGET_PERSISTENCE structure and passes a pointer to this structure in setPacket. Note that the first member of
/// the DISPLAYCONFIG_SET_TARGET_PERSISTENCE structure is the DISPLAYCONFIG_DEVICE_INFO_HEADER.
///
///
/// The function returns one of the following return codes.
///
///
/// Return code
/// Description
///
/// -
/// ERROR_SUCCESS
/// The function succeeded.
///
/// -
/// ERROR_INVALID_PARAMETER
/// The combination of parameters and flags specified are invalid.
///
/// -
/// ERROR_NOT_SUPPORTED
///
/// The system is not running a graphics driver that was written according to the Windows Display Driver Model (WDDM). The function
/// is only supported on a system with a WDDM driver running.
///
///
/// -
/// ERROR_ACCESS_DENIED
///
/// The caller does not have access to the console session. This error occurs if the calling process does not have access to the
/// current desktop or is running on a remote session.
///
///
/// -
/// ERROR_INSUFFICIENT_BUFFER
/// The size of the packet that the caller passes is not big enough.
///
/// -
/// ERROR_GEN_FAILURE
/// An unspecified error occurred.
///
///
///
///
///
/// DisplayConfigSetDeviceInfo can currently only be used to start and stop boot persisted force projection on an analog
/// target. For more information about boot persistence, see Forced Versus Connected Targets.
///
///
/// DisplayConfigSetDeviceInfo can only be used to set DISPLAYCONFIG_DEVICE_INFO_SET_XXX type of information.
/// DisplayConfigSetDeviceInfo fails if the type member of DISPLAYCONFIG_DEVICE_INFO_HEADER is set to one of the
/// DISPLAYCONFIG_DEVICE_INFO_GET_XXX values.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-displayconfigsetdeviceinfo LONG
// DisplayConfigSetDeviceInfo( DISPLAYCONFIG_DEVICE_INFO_HEADER *setPacket );
[DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winuser.h", MSDNShortId = "4050b1f0-a588-427c-a0df-eefdc488fc20")]
public static extern Win32Error DisplayConfigSetDeviceInfo(IntPtr setPacket);
/// The DisplayConfigSetDeviceInfo function sets the properties of a target.
/// The type of the value to set.
/// Contains information to set for the device.
/// Supplied type does not match valid set value.
public static void DisplayConfigSetDeviceInfo(T value) where T : struct
{
if (!CorrespondingTypeAttribute.CanSet(typeof(DISPLAYCONFIG_DEVICE_INFO_TYPE), typeof(T))) throw new ArgumentException("Supplied type does not match valid set value.");
var mem = SafeHGlobalHandle.CreateFromStructure(value);
DisplayConfigSetDeviceInfo((IntPtr)mem).ThrowIfFailed();
}
///
/// The GetDisplayConfigBufferSizes function retrieves the size of the buffers that are required to call the
/// QueryDisplayConfig function.
///
///
/// The type of information to retrieve. The value for the Flags parameter must be one of the following values.
/// QDC_ALL_PATHS
/// The caller requests the table sizes to hold all the possible path combinations.
/// QDC_ONLY_ACTIVE_PATHS
/// The caller requests the table sizes to hold only active paths.
/// QDC_DATABASE_CURRENT
///
/// The caller requests the table sizes to hold the active paths as defined in the persistence database for the currently connected monitors.
///
///
///
/// Pointer to a variable that receives the number of elements in the path information table. The pNumPathArrayElements parameter
/// value is then used by a subsequent call to the QueryDisplayConfig function. This parameter cannot be NULL.
///
///
/// Pointer to a variable that receives the number of elements in the mode information table. The pNumModeInfoArrayElements parameter
/// value is then used by a subsequent call to the QueryDisplayConfig function. This parameter cannot be NULL.
///
///
/// The function returns one of the following return codes.
///
///
/// Return code
/// Description
///
/// -
/// ERROR_SUCCESS
/// The function succeeded.
///
/// -
/// ERROR_INVALID_PARAMETER
/// The combination of parameters and flags that are specified is invalid.
///
/// -
/// ERROR_NOT_SUPPORTED
///
/// The system is not running a graphics driver that was written according to the Windows Display Driver Model (WDDM). The function
/// is only supported on a system with a WDDM driver running.
///
///
/// -
/// ERROR_ACCESS_DENIED
///
/// The caller does not have access to the console session. This error occurs if the calling process does not have access to the
/// current desktop or is running on a remote session.
///
///
/// -
/// ERROR_GEN_FAILURE
/// An unspecified error occurred.
///
///
///
///
///
/// Given the current display path configuration and the requested flags, GetDisplayConfigBufferSizes returns the size of the
/// path and mode tables that are required to store the information. GetDisplayConfigBufferSizes can return values that are
/// slightly larger than are actually required because it determines that all source and target paths are valid; whereas, the driver
/// might place some restrictions on the possible combinations.
///
///
/// As GetDisplayConfigBufferSizes can only determine the required array size of that moment in time, it is possible that
/// between calls to GetDisplayConfigBufferSizes and QueryDisplayConfig the system configuration has changed and the provided
/// array sizes are no longer sufficient to store the new path data.
///
///
/// If a caller is aware that it must enable additional sources and targets, the caller can allocate a larger mode information array
/// than is returned from GetDisplayConfigBufferSizes so that it has the space to add the additional source and target modes
/// after calling QueryDisplayConfig and before calling SetDisplayConfig.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getdisplayconfigbuffersizes LONG
// GetDisplayConfigBufferSizes( UINT32 flags, UINT32 *numPathArrayElements, UINT32 *numModeInfoArrayElements );
[DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winuser.h", MSDNShortId = "5ec7f521-28b5-4922-a3fc-aa4433de69e0")]
public static extern Win32Error GetDisplayConfigBufferSizes(QDC flags, out uint numPathArrayElements, out uint numModeInfoArrayElements);
///
/// The QueryDisplayConfig function retrieves information about all possible display paths for all display devices, or views,
/// in the current setting.
///
///
/// The type of information to retrieve. The value for the Flags parameter must be one of the following values.
/// QDC_ALL_PATHS
/// All the possible path combinations of sources to targets.
///
/// Note In the case of any temporary modes, the QDC_ALL_PATHS setting means the mode data returned may not be the same as
/// that which is stored in the persistence database.
///
/// QDC_ONLY_ACTIVE_PATHS
/// Currently active paths only.
///
/// Note In the case of any temporary modes, the QDC_ONLY_ACTIVE_PATHS setting means the mode data returned may not be the
/// same as that which is stored in the persistence database.
///
/// QDC_DATABASE_CURRENT
/// Active path as defined in the CCD database for the currently connected displays.
///
///
/// Pointer to a variable that contains the number of elements in pPathInfoArray. This parameter cannot be NULL. If
/// QueryDisplayConfig returns ERROR_SUCCESS, pNumPathInfoElements is updated with the number of valid entries in pPathInfoArray.
///
///
/// Pointer to a variable that contains an array of DISPLAYCONFIG_PATH_INFO elements. Each element in pPathInfoArray describes a
/// single path from a source to a target. The source and target mode information indexes are only valid in combination with the
/// pmodeInfoArray tables that are returned for the API at the same time. This parameter cannot be NULL. The pPathInfoArray is
/// always returned in path priority order. For more information about path priority order, see Path Priority Order.
///
///
/// Pointer to a variable that specifies the number in element of the mode information table. This parameter cannot be NULL.
/// If QueryDisplayConfig returns ERROR_SUCCESS, pNumModeInfoArrayElements is updated with the number of valid entries in pModeInfoArray.
///
///
/// Pointer to a variable that contains an array of DISPLAYCONFIG_MODE_INFO elements. This parameter cannot be NULL.
///
///
///
/// Pointer to a variable that receives the identifier of the currently active topology in the CCD database. For a list of possible
/// values, see the DISPLAYCONFIG_TOPOLOGY_ID enumerated type.
///
/// The pCurrentTopologyId parameter is only set when the Flags parameter value is QDC_DATABASE_CURRENT.
///
/// If the Flags parameter value is set to QDC_DATABASE_CURRENT, the pCurrentTopologyId parameter must not be NULL. If the
/// Flags parameter value is not set to QDC_DATABASE_CURRENT, the pCurrentTopologyId parameter value must be NULL.
///
///
///
/// The function returns one of the following return codes.
///
///
/// Return code
/// Description
///
/// -
/// ERROR_SUCCESS
/// The function succeeded.
///
/// -
/// ERROR_INVALID_PARAMETER
/// The combination of parameters and flags that are specified is invalid.
///
/// -
/// ERROR_NOT_SUPPORTED
///
/// The system is not running a graphics driver that was written according to the Windows Display Driver Model (WDDM). The function
/// is only supported on a system with a WDDM driver running.
///
///
/// -
/// ERROR_ACCESS_DENIED
///
/// The caller does not have access to the console session. This error occurs if the calling process does not have access to the
/// current desktop or is running on a remote session.
///
///
/// -
/// ERROR_GEN_FAILURE
/// An unspecified error occurred.
///
/// -
/// ERROR_INSUFFICIENT_BUFFER
/// The supplied path and mode buffer are too small.
///
///
///
///
///
/// As the GetDisplayConfigBufferSizes function can only determine the required array size at a particular moment in time, it is
/// possible that between calls to GetDisplayConfigBufferSizes and QueryDisplayConfig the system configuration will
/// change and the provided array sizes will no longer be sufficient to store the new path data. In this situation,
/// QueryDisplayConfig fails with ERROR_INSUFFICIENT_BUFFER, and the caller should call GetDisplayConfigBufferSizes
/// again to get the new array sizes. The caller should then allocate the correct amount of memory.
///
///
/// QueryDisplayConfig returns paths in the path array that the pPathInfoArray parameter specifies and the source and target
/// modes in the mode array that the pModeInfoArray parameter specifies. QueryDisplayConfig always returns paths in path
/// priority order. If QDC_ALL_PATHS is set in the Flags parameter, QueryDisplayConfig returns all the inactive paths after
/// the active paths.
///
///
/// Full path, source mode, and target mode information is available for all active paths. The ModeInfoIdx members in the
/// DISPLAYCONFIG_PATH_SOURCE_INFO and DISPLAYCONFIG_PATH_TARGET_INFO structures for the source and target are set up for these
/// active paths. For inactive paths, returned source and target mode information is not available; therefore, the target information
/// in the path structure is set to default values, and the source and target mode indexes are marked as invalid. For database
/// queries, if the current connect monitors have an entry, QueryDisplayConfig returns full path, source mode, and target mode
/// information (same as for active paths). However, if the database does not have a entry, QueryDisplayConfig returns just
/// the path information with the default target details (same as for inactive paths).
///
///
/// For an example of how source and target mode information relates to path information, see Relationship of Mode Information to
/// Path Information.
///
///
/// The caller can use DisplayConfigGetDeviceInfo to obtain additional information about the source or target device, for example,
/// the monitor names and monitor preferred mode and source device name.
///
///
/// If a target is currently being force projected, the statusFlags member of the DISPLAYCONFIG_PATH_TARGET_INFO structure has
/// one of the DISPLAYCONFIG_TARGET_FORCED_XXX flags set.
///
///
/// If the QDC_DATABASE_CURRENT flag is set in the Flags parameter, QueryDisplayConfig returns the topology identifier of the
/// active database topology in the variable that the pCurrentTopologyId parameter points to. If the QDC_ALL_PATHS or
/// QDC_ONLY_ACTIVE_PATHS flag is set in the Flags parameter, the pCurrentTopologyId parameter must be set to NULL; otherwise,
/// QueryDisplayConfig returns ERROR_INVALID_PARAMETER.
///
///
/// If a caller calls QueryDisplayConfig with the QDC_DATABASE_CURRENT flag set in the Flags parameter,
/// QueryDisplayConfig initializes the DISPLAYCONFIG_2DREGION structure that is specified in the totalSize member of
/// the DISPLAYCONFIG_VIDEO_SIGNAL_INFO structure to zeros and does not complete DISPLAYCONFIG_2DREGION.
///
///
/// The DEVMODE structure that is returned by the EnumDisplaySettings Win32 function (described in the Windows SDK documentation)
/// contains information that relates to both the source and target modes. However, the CCD APIs explicitly separate the source and
/// target mode components.
///
/// DPI Virtualization
///
/// This API does not participate in DPI virtualization. All sizes in the DEVMODE structure are in terms of physical pixels, and are
/// not related to the calling context.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-querydisplayconfig LONG QueryDisplayConfig( UINT32 flags,
// UINT32 *numPathArrayElements, DISPLAYCONFIG_PATH_INFO *pathArray, UINT32 *numModeInfoArrayElements, DISPLAYCONFIG_MODE_INFO
// *modeInfoArray, DISPLAYCONFIG_TOPOLOGY_ID *currentTopologyId );
[DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winuser.h", MSDNShortId = "b1792d7f-f216-4250-a6b6-a11b251a9cec")]
public static extern Win32Error QueryDisplayConfig(QDC flags, ref uint numPathArrayElements, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] DISPLAYCONFIG_PATH_INFO[] pathArray,
ref uint numModeInfoArrayElements, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] DISPLAYCONFIG_MODE_INFO[] modeInfoArray, IntPtr currentTopologyId = default);
///
/// The QueryDisplayConfig function retrieves information about all possible display paths for all display devices, or views,
/// in the current setting.
///
///
/// The type of information to retrieve. The value for the Flags parameter must be one of the following values.
/// QDC_ALL_PATHS
/// All the possible path combinations of sources to targets.
///
/// Note In the case of any temporary modes, the QDC_ALL_PATHS setting means the mode data returned may not be the same as
/// that which is stored in the persistence database.
///
/// QDC_ONLY_ACTIVE_PATHS
/// Currently active paths only.
///
/// Note In the case of any temporary modes, the QDC_ONLY_ACTIVE_PATHS setting means the mode data returned may not be the
/// same as that which is stored in the persistence database.
///
/// QDC_DATABASE_CURRENT
/// Active path as defined in the CCD database for the currently connected displays.
///
///
/// Pointer to a variable that contains the number of elements in pPathInfoArray. This parameter cannot be NULL. If
/// QueryDisplayConfig returns ERROR_SUCCESS, pNumPathInfoElements is updated with the number of valid entries in pPathInfoArray.
///
///
/// Pointer to a variable that contains an array of DISPLAYCONFIG_PATH_INFO elements. Each element in pPathInfoArray describes a
/// single path from a source to a target. The source and target mode information indexes are only valid in combination with the
/// pmodeInfoArray tables that are returned for the API at the same time. This parameter cannot be NULL. The pPathInfoArray is
/// always returned in path priority order. For more information about path priority order, see Path Priority Order.
///
///
/// Pointer to a variable that specifies the number in element of the mode information table. This parameter cannot be NULL.
/// If QueryDisplayConfig returns ERROR_SUCCESS, pNumModeInfoArrayElements is updated with the number of valid entries in pModeInfoArray.
///
///
/// Pointer to a variable that contains an array of DISPLAYCONFIG_MODE_INFO elements. This parameter cannot be NULL.
///
///
///
/// Pointer to a variable that receives the identifier of the currently active topology in the CCD database. For a list of possible
/// values, see the DISPLAYCONFIG_TOPOLOGY_ID enumerated type.
///
/// The pCurrentTopologyId parameter is only set when the Flags parameter value is QDC_DATABASE_CURRENT.
///
/// If the Flags parameter value is set to QDC_DATABASE_CURRENT, the pCurrentTopologyId parameter must not be NULL. If the
/// Flags parameter value is not set to QDC_DATABASE_CURRENT, the pCurrentTopologyId parameter value must be NULL.
///
///
///
/// The function returns one of the following return codes.
///
///
/// Return code
/// Description
///
/// -
/// ERROR_SUCCESS
/// The function succeeded.
///
/// -
/// ERROR_INVALID_PARAMETER
/// The combination of parameters and flags that are specified is invalid.
///
/// -
/// ERROR_NOT_SUPPORTED
///
/// The system is not running a graphics driver that was written according to the Windows Display Driver Model (WDDM). The function
/// is only supported on a system with a WDDM driver running.
///
///
/// -
/// ERROR_ACCESS_DENIED
///
/// The caller does not have access to the console session. This error occurs if the calling process does not have access to the
/// current desktop or is running on a remote session.
///
///
/// -
/// ERROR_GEN_FAILURE
/// An unspecified error occurred.
///
/// -
/// ERROR_INSUFFICIENT_BUFFER
/// The supplied path and mode buffer are too small.
///
///
///
///
///
/// As the GetDisplayConfigBufferSizes function can only determine the required array size at a particular moment in time, it is
/// possible that between calls to GetDisplayConfigBufferSizes and QueryDisplayConfig the system configuration will
/// change and the provided array sizes will no longer be sufficient to store the new path data. In this situation,
/// QueryDisplayConfig fails with ERROR_INSUFFICIENT_BUFFER, and the caller should call GetDisplayConfigBufferSizes
/// again to get the new array sizes. The caller should then allocate the correct amount of memory.
///
///
/// QueryDisplayConfig returns paths in the path array that the pPathInfoArray parameter specifies and the source and target
/// modes in the mode array that the pModeInfoArray parameter specifies. QueryDisplayConfig always returns paths in path
/// priority order. If QDC_ALL_PATHS is set in the Flags parameter, QueryDisplayConfig returns all the inactive paths after
/// the active paths.
///
///
/// Full path, source mode, and target mode information is available for all active paths. The ModeInfoIdx members in the
/// DISPLAYCONFIG_PATH_SOURCE_INFO and DISPLAYCONFIG_PATH_TARGET_INFO structures for the source and target are set up for these
/// active paths. For inactive paths, returned source and target mode information is not available; therefore, the target information
/// in the path structure is set to default values, and the source and target mode indexes are marked as invalid. For database
/// queries, if the current connect monitors have an entry, QueryDisplayConfig returns full path, source mode, and target mode
/// information (same as for active paths). However, if the database does not have a entry, QueryDisplayConfig returns just
/// the path information with the default target details (same as for inactive paths).
///
///
/// For an example of how source and target mode information relates to path information, see Relationship of Mode Information to
/// Path Information.
///
///
/// The caller can use DisplayConfigGetDeviceInfo to obtain additional information about the source or target device, for example,
/// the monitor names and monitor preferred mode and source device name.
///
///
/// If a target is currently being force projected, the statusFlags member of the DISPLAYCONFIG_PATH_TARGET_INFO structure has
/// one of the DISPLAYCONFIG_TARGET_FORCED_XXX flags set.
///
///
/// If the QDC_DATABASE_CURRENT flag is set in the Flags parameter, QueryDisplayConfig returns the topology identifier of the
/// active database topology in the variable that the pCurrentTopologyId parameter points to. If the QDC_ALL_PATHS or
/// QDC_ONLY_ACTIVE_PATHS flag is set in the Flags parameter, the pCurrentTopologyId parameter must be set to NULL; otherwise,
/// QueryDisplayConfig returns ERROR_INVALID_PARAMETER.
///
///
/// If a caller calls QueryDisplayConfig with the QDC_DATABASE_CURRENT flag set in the Flags parameter,
/// QueryDisplayConfig initializes the DISPLAYCONFIG_2DREGION structure that is specified in the totalSize member of
/// the DISPLAYCONFIG_VIDEO_SIGNAL_INFO structure to zeros and does not complete DISPLAYCONFIG_2DREGION.
///
///
/// The DEVMODE structure that is returned by the EnumDisplaySettings Win32 function (described in the Windows SDK documentation)
/// contains information that relates to both the source and target modes. However, the CCD APIs explicitly separate the source and
/// target mode components.
///
/// DPI Virtualization
///
/// This API does not participate in DPI virtualization. All sizes in the DEVMODE structure are in terms of physical pixels, and are
/// not related to the calling context.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-querydisplayconfig LONG QueryDisplayConfig( UINT32 flags,
// UINT32 *numPathArrayElements, DISPLAYCONFIG_PATH_INFO *pathArray, UINT32 *numModeInfoArrayElements, DISPLAYCONFIG_MODE_INFO
// *modeInfoArray, DISPLAYCONFIG_TOPOLOGY_ID *currentTopologyId );
[DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winuser.h", MSDNShortId = "b1792d7f-f216-4250-a6b6-a11b251a9cec")]
public static extern Win32Error QueryDisplayConfig(QDC flags, ref uint numPathArrayElements, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] DISPLAYCONFIG_PATH_INFO[] pathArray,
ref uint numModeInfoArrayElements, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] DISPLAYCONFIG_MODE_INFO[] modeInfoArray, out DISPLAYCONFIG_TOPOLOGY_ID currentTopologyId);
///
/// The QueryDisplayConfig function retrieves information about all possible display paths for all display devices, or views,
/// in the current setting. This method also calls GetDisplayConfigBufferSizes to determine output sizing.
///
///
/// The type of information to retrieve. The value for the Flags parameter must be one of the following values.
/// QDC_ALL_PATHS
/// All the possible path combinations of sources to targets.
///
/// Note In the case of any temporary modes, the QDC_ALL_PATHS setting means the mode data returned may not be the same as
/// that which is stored in the persistence database.
///
/// QDC_ONLY_ACTIVE_PATHS
/// Currently active paths only.
///
/// Note In the case of any temporary modes, the QDC_ONLY_ACTIVE_PATHS setting means the mode data returned may not be the
/// same as that which is stored in the persistence database.
///
/// QDC_DATABASE_CURRENT
/// Active path as defined in the CCD database for the currently connected displays.
///
///
/// The resulting array of DISPLAYCONFIG_PATH_INFO elements. Each element in pPathInfoArray describes a single path from a source to
/// a target. The source and target mode information indexes are only valid in combination with the pmodeInfoArray tables that are
/// returned for the API at the same time. This parameter cannot be NULL. The pPathInfoArray is always returned in path
/// priority order. For more information about path priority order, see Path Priority Order.
///
/// The resulting array of DISPLAYCONFIG_MODE_INFO elements.
///
///
/// Pointer to a variable that receives the identifier of the currently active topology in the CCD database. For a list of possible
/// values, see the DISPLAYCONFIG_TOPOLOGY_ID enumerated type.
///
/// The pCurrentTopologyId parameter is only set when the Flags parameter value is QDC_DATABASE_CURRENT.
///
/// If the Flags parameter value is set to QDC_DATABASE_CURRENT, the pCurrentTopologyId parameter must not be NULL. If the
/// Flags parameter value is not set to QDC_DATABASE_CURRENT, the pCurrentTopologyId parameter value must be NULL.
///
///
///
/// The function returns one of the following return codes.
///
///
/// Return code
/// Description
///
/// -
/// ERROR_SUCCESS
/// The function succeeded.
///
/// -
/// ERROR_INVALID_PARAMETER
/// The combination of parameters and flags that are specified is invalid.
///
/// -
/// ERROR_NOT_SUPPORTED
///
/// The system is not running a graphics driver that was written according to the Windows Display Driver Model (WDDM). The function
/// is only supported on a system with a WDDM driver running.
///
///
/// -
/// ERROR_ACCESS_DENIED
///
/// The caller does not have access to the console session. This error occurs if the calling process does not have access to the
/// current desktop or is running on a remote session.
///
///
/// -
/// ERROR_GEN_FAILURE
/// An unspecified error occurred.
///
/// -
/// ERROR_INSUFFICIENT_BUFFER
/// The supplied path and mode buffer are too small.
///
///
///
///
///
/// QueryDisplayConfig returns paths in the path array that the pPathInfoArray parameter specifies and the source and target
/// modes in the mode array that the pModeInfoArray parameter specifies. QueryDisplayConfig always returns paths in path
/// priority order. If QDC_ALL_PATHS is set in the Flags parameter, QueryDisplayConfig returns all the inactive paths after
/// the active paths.
///
///
/// Full path, source mode, and target mode information is available for all active paths. The ModeInfoIdx members in the
/// DISPLAYCONFIG_PATH_SOURCE_INFO and DISPLAYCONFIG_PATH_TARGET_INFO structures for the source and target are set up for these
/// active paths. For inactive paths, returned source and target mode information is not available; therefore, the target information
/// in the path structure is set to default values, and the source and target mode indexes are marked as invalid. For database
/// queries, if the current connect monitors have an entry, QueryDisplayConfig returns full path, source mode, and target mode
/// information (same as for active paths). However, if the database does not have a entry, QueryDisplayConfig returns just
/// the path information with the default target details (same as for inactive paths).
///
///
/// For an example of how source and target mode information relates to path information, see Relationship of Mode Information to
/// Path Information.
///
///
/// The caller can use DisplayConfigGetDeviceInfo to obtain additional information about the source or target device, for example,
/// the monitor names and monitor preferred mode and source device name.
///
///
/// If a target is currently being force projected, the statusFlags member of the DISPLAYCONFIG_PATH_TARGET_INFO structure has
/// one of the DISPLAYCONFIG_TARGET_FORCED_XXX flags set.
///
///
/// If the QDC_DATABASE_CURRENT flag is set in the Flags parameter, QueryDisplayConfig returns the topology identifier of the
/// active database topology in the variable that the pCurrentTopologyId parameter points to. If the QDC_ALL_PATHS or
/// QDC_ONLY_ACTIVE_PATHS flag is set in the Flags parameter, the pCurrentTopologyId parameter must be set to NULL; otherwise,
/// QueryDisplayConfig returns ERROR_INVALID_PARAMETER.
///
///
/// If a caller calls QueryDisplayConfig with the QDC_DATABASE_CURRENT flag set in the Flags parameter,
/// QueryDisplayConfig initializes the DISPLAYCONFIG_2DREGION structure that is specified in the totalSize member of
/// the DISPLAYCONFIG_VIDEO_SIGNAL_INFO structure to zeros and does not complete DISPLAYCONFIG_2DREGION.
///
///
/// The DEVMODE structure that is returned by the EnumDisplaySettings Win32 function (described in the Windows SDK documentation)
/// contains information that relates to both the source and target modes. However, the CCD APIs explicitly separate the source and
/// target mode components.
///
/// DPI Virtualization
///
/// This API does not participate in DPI virtualization. All sizes in the DEVMODE structure are in terms of physical pixels, and are
/// not related to the calling context.
///
///
[PInvokeData("winuser.h", MSDNShortId = "b1792d7f-f216-4250-a6b6-a11b251a9cec")]
public static Win32Error QueryDisplayConfig(QDC flags, out DISPLAYCONFIG_PATH_INFO[] pathArray, out DISPLAYCONFIG_MODE_INFO[] modeInfoArray, out DISPLAYCONFIG_TOPOLOGY_ID currentTopologyId)
{
Win32Error err;
do
{
err = GetDisplayConfigBufferSizes(flags, out var cPath, out var cMode);
pathArray = new DISPLAYCONFIG_PATH_INFO[err.Failed ? 0 : cPath];
modeInfoArray = new DISPLAYCONFIG_MODE_INFO[err.Failed ? 0 : cMode];
currentTopologyId = 0;
if (err.Failed) return err;
if (flags.IsFlagSet(QDC.QDC_DATABASE_CURRENT))
err = QueryDisplayConfig(flags, ref cPath, pathArray, ref cMode, modeInfoArray, out currentTopologyId);
else
err = QueryDisplayConfig(flags, ref cPath, pathArray, ref cMode, modeInfoArray);
if (err.Succeeded || err != Win32Error.ERROR_INSUFFICIENT_BUFFER) return err;
} while (err == Win32Error.ERROR_INSUFFICIENT_BUFFER);
return err;
}
///
/// The SetDisplayConfig function modifies the display topology, source, and target modes by exclusively enabling the
/// specified paths in the current session.
///
/// Number of elements in pathArray.
///
/// Array of all display paths that are to be set. Only the paths within this array that have the DISPLAYCONFIG_PATH_ACTIVE flag set
/// in the flags member of DISPLAYCONFIG_PATH_INFO are set. This parameter can be NULL. The order in which active paths
/// appear in this array determines the path priority. For more information about path priority order, see Path Priority Order.
///
/// Number of elements in modeInfoArray.
///
/// Array of display source and target mode information (DISPLAYCONFIG_MODE_INFO) that is referenced by the modeInfoIdx member
/// of DISPLAYCONFIG_PATH_SOURCE_INFO and DISPLAYCONFIG_PATH_TARGET_INFO element of path information from pathArray. This parameter
/// can be NULL.
///
///
///
/// A bitwise OR of flag values that indicates the behavior of this function. This parameter can be one the following values, or a
/// combination of the following values; 0 is not valid.
///
/// SDC_APPLY
/// The resulting topology, source, and target mode is set.
/// SDC_NO_OPTIMIZATION
///
/// A modifier to the SDC_APPLY flag. This causes the change mode to be forced all the way down to the driver for each active display.
///
/// SDC_USE_SUPPLIED_DISPLAY_CONFIG
///
/// The topology, source, and target mode information that are supplied in the pathArray and the modeInfoArray parameters are used,
/// rather than looking up the configuration in the database.
///
/// SDC_SAVE_TO_DATABASE
/// The resulting topology, source, and target mode are saved to the database.
/// SDC_VALIDATE
/// The system tests for the requested topology, source, and target mode information to determine whether it can be set.
/// SDC_ALLOW_CHANGES
///
/// If required, the function can modify the specified source and target mode information in order to create a functional display
/// path set.
///
/// SDC_TOPOLOGY_CLONE
/// The caller requests the last clone configuration from the persistence database.
/// SDC_TOPOLOGY_EXTEND
/// The caller requests the last extended configuration from the persistence database.
/// SDC_TOPOLOGY_INTERNAL
/// The caller requests the last internal configuration from the persistence database.
/// SDC_TOPOLOGY_EXTERNAL
/// The caller requests the last external configuration from the persistence database.
/// SDC_TOPOLOGY_SUPPLIED
///
/// The caller provides the path data so the function only queries the persistence database to find and use the source and target mode.
///
/// SDC_USE_DATABASE_CURRENT
///
/// The caller requests a combination of all four SDC_TOPOLOGY_XXX configurations. This value informs the API to set the last known
/// display configuration for the current connected monitors.
///
/// SDC_PATH_PERSIST_IF_REQUIRED
///
/// When the function processes a SDC_TOPOLOGY_XXX request, it can force path persistence on a target to satisfy the request if
/// necessary. For information about the other flags that this flag can be combined with, see the following list.
///
/// SDC_FORCE_MODE_ENUMERATION
///
/// The caller requests that the driver is given an opportunity to update the GDI mode list while SetDisplayConfig sets the
/// new display configuration. This flag value is only valid when the SDC_USE_SUPPLIED_DISPLAY_CONFIG and SDC_APPLY flag values are
/// also specified.
///
/// SDC_ALLOW_PATH_ORDER_CHANGES
///
/// A modifier to the SDC_TOPOLOGY_SUPPLIED flag that indicates that SetDisplayConfig should ignore the path order of the
/// supplied topology when searching the database. When this flag is set, the topology set is the most recent topology that contains
/// all the paths regardless of the path order.
///
/// The following list contains valid combinations of values for the Flags parameter:
///
/// -
/// Either SDC_APPLY or SDC_VALIDATE must be set, but not both.
///
/// -
///
/// Either SDC_USE_SUPPLIED_DISPLAY_CONFIG or any combinations of SDC_TOPOLOGY_XXX must be set. SDC_USE_SUPPLIED_DISPLAY_CONFIG
/// cannot be set with any SDC_TOPOLOGY_XXX flag.
///
///
/// -
/// SDC_NO_OPTIMIZATION can only be set with SDC_APPLY.
///
/// -
/// SDC_ALLOW_CHANGES is allowed with any other valid combination.
///
/// -
/// SDC_SAVE_TO_DATABASE can only be set with SDC_USE_SUPPLIED_DISPLAY_CONFIG.
///
/// -
/// SDC_PATH_PERSIST_IF_REQUIRED cannot be used with SDC_USE_SUPPLIED_DISPLAY_CONFIG or SDC_TOPOLOGY_SUPPLIED.
///
/// -
/// SDC_FORCE_MODE_ENUMERATION is only valid when SDC_APPLY and SDC_USE_SUPPLIED_DISPLAY_CONFIG are specified.
///
/// -
/// SDC_ALLOW_PATH_ORDER_CHANGES is allowed only when SDC_TOPOLOGY_SUPPLIED is specified.
///
/// -
///
/// SDC_TOPOLOGY_SUPPLIED cannot be used with any other SDC_TOPOLOGY_XXX flag. Because of a validation issue, if a caller violates
/// this rule, SetDisplayConfig does not fail. However, SetDisplayConfig ignores the SDC_TOPOLOGY_SUPPLIED flag.
///
///
///
///
/// SDC_TOPOLOGY_XXX flags can be used in combinations. For example, if SDC_TOPOLOGY_CLONE and SDC_TOPOLOGY_EXTEND are set, the API
/// uses the most recent clone or extend topology, which every topology was set with most recently for the current connected monitors.
///
///
///
/// The function returns one of the following return codes.
///
///
/// Return code
/// Description
///
/// -
/// ERROR_SUCCESS
/// The function succeeded.
///
/// -
/// ERROR_INVALID_PARAMETER
/// The combination of parameters and flags specified is invalid.
///
/// -
/// ERROR_NOT_SUPPORTED
///
/// The system is not running a graphics driver that was written according to the Windows Display Driver Model (WDDM). The function
/// is only supported on a system with a WDDM driver running.
///
///
/// -
/// ERROR_ACCESS_DENIED
///
/// The caller does not have access to the console session. This error occurs if the calling process does not have access to the
/// current desktop or is running on a remote session.
///
///
/// -
/// ERROR_GEN_FAILURE
/// An unspecified error occurred.
///
/// -
/// ERROR_BAD_CONFIGURATION
/// The function could not find a workable solution for the source and target modes that the caller did not specify.
///
///
///
///
///
/// The SetDisplayConfig function takes the active display paths with any specified source and target mode information and
/// uses best mode logic to generate any missing source and target mode information. This function then sets the complete display path.
///
///
/// The ModeInfoIdx members in the DISPLAYCONFIG_PATH_SOURCE_INFO and DISPLAYCONFIG_PATH_TARGET_INFO structures are used to
/// indicate whether source and target mode are supplied for a given active path. If the index value is
/// DISPLAYCONFIG_PATH_MODE_IDX_INVALID for either, this indicates the mode information is not being specified. It is valid for the
/// path plus source mode or the path plus source and target mode information to be specified for a given path. However, it is not
/// valid for the path plus target mode to be specified without the source mode.
///
///
/// The source and target modes for each source and target identifiers can only appear in the modeInfoArray array once. For example,
/// a source mode for source identifier S1 can only appear in the table once; if multiple paths reference the same source, they have
/// to use the same ModeInfoIdx.
///
///
/// The expectation is that most callers use QueryDisplayConfig to get the current configuration along with other valid possibilities
/// and then use SetDisplayConfig to test and set the configuration.
///
/// The order in which the active paths appear in the PathArray array determines the path priority.
///
/// By default, SetDisplayConfig never changes any supplied path, source mode, or target mode information. If best mode logic
/// cannot find a solution without changing the specified display path information, SetDisplayConfig fails with
/// ERROR_BAD_CONFIGURATION. In this case, the caller should specify the SDC_ALLOW_CHANGES flag to allow the function to tweak some
/// of the specified source and mode details to allow the display path change to be successful.
///
///
/// If the specified or calculated source and target modes have the same dimensions, SetDisplayConfig automatically sets the
/// path scaling to DISPLAYCONFIG_PPR_IDENTITY before setting the display path and saving it in the database. For information about
/// how SetDisplayConfig handles scaling, see Scaling the Desktop Image.
///
///
/// When the caller specifies the SDC_USE_SUPPLIED_DISPLAY_CONFIG flag to set a clone path and if any source mode indexes are invalid
/// in the path array, SetDisplayConfig determines that all of the source mode indexes from that source are invalid.
/// SetDisplayConfig uses the best mode logic to determine the source mode information.
///
///
/// Except for the SDC_TOPOLOGY_SUPPLIED flag (for more information about SDC_TOPOLOGY_SUPPLIED, see the following paragraph), the
/// SDC_TOPOLOGY_XXX flags set last display path settings, including the source and target mode information for that topology type.
/// For information about valid SDC_TOPOLOGY_XXX flag combinations, see the Flags parameter description. The pathArray and
/// modeInfoArray parameters must be NULL, and their associated sizes must be zero. For example, if SDC_TOPOLOGY_CLONE and
/// SDC_TOPOLOGY_EXTEND are set, this function uses the most recent clone or extend display path configuration. If a single topology
/// type is requested, the last configuration of that type is used. If that topology had never been set before,
/// SetDisplayConfig uses the best topology logic to find the best topology, and then best mode logic to find the best source
/// and target mode to use. If a combination of the topology flags had been set and none of them had database entries, the following
/// priority is used. For laptops: clone, extend, internal, and then external; for desktops the priority is extend and then clone.
///
///
/// The caller can specify the SDC_TOPOLOGY_SUPPLIED flag to indicate that it sets just the path information (topology) and requests
/// that SetDisplayConfig obtains and then uses the source and target mode information from the persistence database. If the
/// active paths that the caller supplies do not have an entry in the persistence database, SetDisplayConfig fails. In this
/// case, if the caller calls SetDisplayConfig again with the same path data but with the SDC_USE_SUPPLIED_DISPLAY_CONFIG flag
/// set, SetDisplayConfig uses best mode logic to create the source and target mode information. When the caller specifies
/// SDC_TOPOLOGY_SUPPLIED, the caller must set the numModeInfoArrayElements parameter to zero and the modeInfoArray parameter to
/// NULL; however, the caller must set the pathArray and numPathArrayElements parameters for the path information that the
/// caller requires. The caller must mark all the source and target mode indexes as invalid (DISPLAYCONFIG_PATH_MODE_IDX_INVALID) in
/// this path data.
///
///
/// The following table provides some common scenarios where SetDisplayConfig is called along with the flag combinations that
/// the caller passes to the Flags parameter to achieve the scenarios.
///
///
///
/// Scenario
/// Flag combination
///
/// -
/// Test whether a specified display configuration is supported on the computer
/// SDC_VALIDATE | SDC_USE_SUPPLIED_DISPLAY_CONFIG
///
/// -
/// Set a specified display configuration and save to the database
/// SDC_APPLY | SDC_USE_SUPPLIED_DISPLAY_CONFIG | SDC_SAVE_TO_DATABASE
///
/// -
/// Set a temporary display configuration (that is, the display configuration will not be saved)
/// SDC_APPLY | SDC_USE_SUPPLIED_DISPLAY_CONFIG
///
/// -
/// Test whether clone is supported on the computer
/// SDC_VALIDATE | SDC_TOPOLOGY_CLONE
///
/// -
/// Set clone topology
/// SDC_APPLY | SDC_TOPOLOGY_CLONE
///
/// -
/// Set clone topology and allow path persistence to be enabled if required to satisfy the request
/// SDC_APPLY | SDC_TOPOLOGY_CLONE | SDC_PATH_PERSIST_IF_REQUIRED
///
/// -
/// Return from a temporary mode to the last saved display configuration
/// SDC_APPLY| SDC_USE_DATABASE_CURRENT
///
/// -
///
/// Given only the path information, set the display configuration with the source and target information from the database for the
/// paths and ignore the path order
///
/// SDC_APPLY | SDC_TOPOLOGY_SUPPLIED | SDC_ALLOW_PATH_ORDER_CHANGES
///
///
/// DPI Virtualization
///
/// This API does not participate in DPI virtualization. All sizes in the DEVMODE structure are in terms of physical pixels, and are
/// not related to the calling context.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setdisplayconfig LONG SetDisplayConfig( UINT32
// numPathArrayElements, DISPLAYCONFIG_PATH_INFO *pathArray, UINT32 numModeInfoArrayElements, DISPLAYCONFIG_MODE_INFO *modeInfoArray,
// UINT32 flags );
[DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winuser.h", MSDNShortId = "9f649fa0-ffb2-44c6-9a66-049f888e3b04")]
public static extern Win32Error SetDisplayConfig(uint numPathArrayElements, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), Optional] DISPLAYCONFIG_PATH_INFO[] pathArray,
uint numModeInfoArrayElements, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2), Optional] DISPLAYCONFIG_MODE_INFO[] modeInfoArray, SDC flags);
}
}