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); } }