private void InitializeRuntimeDeviceAdapterNameToAdapterIdMapping() { mCurrentRuntimeDeviceAdapterNamesToAdapterIds = new Dictionary <string, CCD.LUID>(); // Initialize the mapping of device names to adapter IDs. // Start with querying all display paths. int numPathArrayElements; int numModeInfoArrayElements; Win32Utilities.ThrowIfResultCodeNotSuccess( CCD.GetDisplayConfigBufferSizes( CCD.QueryDisplayFlags.AllPaths, out numPathArrayElements, out numModeInfoArrayElements)); CCD.DisplayConfigPathInfo[] pathInfoArray = new CCD.DisplayConfigPathInfo[numPathArrayElements]; CCD.DisplayConfigModeInfo[] modeInfoArray = new CCD.DisplayConfigModeInfo[numModeInfoArrayElements]; Win32Utilities.ThrowIfResultCodeNotSuccess( CCD.QueryDisplayConfig( CCD.QueryDisplayFlags.AllPaths, ref numPathArrayElements, pathInfoArray, ref numModeInfoArrayElements, modeInfoArray, IntPtr.Zero)); Dictionary <CCD.LUID, string> adapterIdToAdapterName = new Dictionary <CCD.LUID, string>(); // Find the mapping for each unique LUID -> device adapter name. // Don't use a foreach here because there are some cases where QueryDisplayConfig changes // the length of pathInfoArray to have more elements than numPathArrayElements would indicate, // with the extra elements invalidly initialized to 0s in all of its members. for (int i = 0; i < numPathArrayElements; i++) { CCD.DisplayConfigPathInfo pathInfo = pathInfoArray[i]; if (!adapterIdToAdapterName.ContainsKey(pathInfo.sourceInfo.adapterId)) { CCD.DisplayConfigAdapterName adapterName = new CCD.DisplayConfigAdapterName(); adapterName.header.type = CCD.DisplayConfigDeviceInfoType.GetAdapterName; adapterName.header.adapterId = pathInfo.sourceInfo.adapterId; adapterName.header.size = (uint)Marshal.SizeOf(adapterName); Win32Utilities.ThrowIfResultCodeNotSuccess(CCD.DisplayConfigGetDeviceInfo(ref adapterName)); adapterIdToAdapterName.Add( adapterName.header.adapterId, adapterName.adapterDevicePath); } } // Flip the mapping to adapter name to LUID for usage by DisplayPresets. foreach (KeyValuePair <CCD.LUID, string> luidStringPair in adapterIdToAdapterName) { mCurrentRuntimeDeviceAdapterNamesToAdapterIds.Add( luidStringPair.Value, luidStringPair.Key); } }
/// <summary> /// Gets the display target name. /// </summary> /// <param name="targetAdapterId"></param> /// <param name="targetId"></param> /// <returns></returns> static private CCD.DisplayConfigTargetDeviceName GetTargetDeviceName(CCD.LUID targetAdapterId, uint targetId) { CCD.DisplayConfigTargetDeviceName targetDeviceName = new CCD.DisplayConfigTargetDeviceName(); targetDeviceName.header.type = CCD.DisplayConfigDeviceInfoType.GetTargetName; targetDeviceName.header.size = (uint)System.Runtime.InteropServices.Marshal.SizeOf(targetDeviceName); targetDeviceName.header.adapterId = targetAdapterId; targetDeviceName.header.id = targetId; Win32Utilities.ThrowIfResultCodeNotSuccess(CCD.DisplayConfigGetDeviceInfo(ref targetDeviceName)); return(targetDeviceName); }
public static void TestCCDExampleCode(CCD.QueryDisplayFlags queryDisplayFlags) { int resultCode; int numPathArrayElements; int numModeInfoArrayElements; // Get buffer size required to enumerate all valid paths. resultCode = CCD.GetDisplayConfigBufferSizes(queryDisplayFlags, out numPathArrayElements, out numModeInfoArrayElements); Win32Utilities.ThrowIfResultCodeNotSuccess(resultCode); CCD.DisplayConfigPathInfo[] pathInfoArray = new CCD.DisplayConfigPathInfo[numPathArrayElements]; CCD.DisplayConfigModeInfo[] modeInfoArray = new CCD.DisplayConfigModeInfo[numModeInfoArrayElements]; resultCode = CCD.QueryDisplayConfig( queryDisplayFlags, ref numPathArrayElements, pathInfoArray, ref numModeInfoArrayElements, modeInfoArray, IntPtr.Zero); Win32Utilities.ThrowIfResultCodeNotSuccess(resultCode); foreach (CCD.DisplayConfigPathInfo configPathInfo in pathInfoArray) { ConsoleOutputUtilities.WriteDisplayConfigPathInfoToConsole(configPathInfo); Console.WriteLine(); } foreach (CCD.DisplayConfigModeInfo configModeInfo in modeInfoArray) { ConsoleOutputUtilities.WriteDisplayConfigModeInfoToConsole(configModeInfo); Console.WriteLine(); } // Find and store the primary path based by looking for an active path that is located at desktop position // 0,0 CCD.DisplayConfigPathInfo primaryPath = new CCD.DisplayConfigPathInfo(); bool primaryPathFound = false; foreach (CCD.DisplayConfigPathInfo configPathInfo in pathInfoArray) { if ((configPathInfo.flags & (uint)CCD.DisplayConfigFlags.PathActive) > 0) { if (configPathInfo.sourceInfo.modeInfoIdx > modeInfoArray.Length - 1) { throw new Exception("Config Path Info Source Mode Info Index is out of range."); } CCD.DisplayConfigModeInfo modeInfo = modeInfoArray[configPathInfo.sourceInfo.modeInfoIdx]; if (modeInfo.infoType == CCD.DisplayConfigModeInfoType.Source && modeInfo.sourceMode.position.x == 0 && modeInfo.sourceMode.position.y == 0) { // Bingo primaryPath = configPathInfo; primaryPathFound = true; break; } } } if (!primaryPathFound) { throw new Exception("Failed to find primary display path!"); } CCD.DisplayConfigTargetDeviceName dcTargetDeviceName = new CCD.DisplayConfigTargetDeviceName(); dcTargetDeviceName.header.type = CCD.DisplayConfigDeviceInfoType.GetTargetName; dcTargetDeviceName.header.size = (uint)Marshal.SizeOf(dcTargetDeviceName); dcTargetDeviceName.header.adapterId = primaryPath.targetInfo.adapterId; dcTargetDeviceName.header.id = primaryPath.targetInfo.id; resultCode = CCD.DisplayConfigGetDeviceInfo(ref dcTargetDeviceName); Win32Utilities.ThrowIfResultCodeNotSuccess(resultCode); ConsoleOutputUtilities.WriteDisplayConfigTargetDeviceNameToConsole(dcTargetDeviceName); Console.WriteLine(); CCD.DisplayConfigSourceDeviceName dcSourceDeviceName = new CCD.DisplayConfigSourceDeviceName(); dcSourceDeviceName.header.type = CCD.DisplayConfigDeviceInfoType.GetSourceName; dcSourceDeviceName.header.size = (uint)Marshal.SizeOf(dcSourceDeviceName); dcSourceDeviceName.header.adapterId = primaryPath.sourceInfo.adapterId; dcSourceDeviceName.header.id = primaryPath.sourceInfo.id; resultCode = CCD.DisplayConfigGetDeviceInfo(ref dcSourceDeviceName); Win32Utilities.ThrowIfResultCodeNotSuccess(resultCode); ConsoleOutputUtilities.WriteDisplayConfigSourceDeviceNameToConsole(dcSourceDeviceName); CCD.DisplayConfigAdapterName dcAdapterName = new CCD.DisplayConfigAdapterName(); dcAdapterName.header.type = CCD.DisplayConfigDeviceInfoType.GetAdapterName; dcAdapterName.header.size = (uint)Marshal.SizeOf(dcAdapterName); dcAdapterName.header.adapterId = primaryPath.sourceInfo.adapterId; Win32Utilities.ThrowIfResultCodeNotSuccess( CCD.DisplayConfigGetDeviceInfo(ref dcAdapterName)); ConsoleOutputUtilities.WriteDisplayConfigAdapterNameToConsole(dcAdapterName); CCD.DisplayConfigTargetPreferredMode dcTargetPreferredMode = new CCD.DisplayConfigTargetPreferredMode(); dcTargetPreferredMode.header.type = CCD.DisplayConfigDeviceInfoType.GetTargetPreferredMode; dcTargetPreferredMode.header.size = (uint)Marshal.SizeOf(dcTargetPreferredMode); dcTargetPreferredMode.header.adapterId = primaryPath.targetInfo.adapterId; dcTargetPreferredMode.header.id = primaryPath.targetInfo.id; Win32Utilities.ThrowIfResultCodeNotSuccess(CCD.DisplayConfigGetDeviceInfo(ref dcTargetPreferredMode)); }
/// <summary> /// Records the current display configuration as a display preset. /// </summary> /// <param name="presetName">Name of the preset to create</param> /// <returns>A DisplayPreset with the current configuration and supplied name. /// Throws exception if failed to get display configuration paths and modes.</returns> static public DisplayPreset RecordCurrentConfiguration(string presetName) { DisplayPreset displayPreset = null; const CCD.QueryDisplayFlags OnlyActivePathsFlag = CCD.QueryDisplayFlags.OnlyActivePaths; int numPathArrayElements; int numModeInfoArrayElements; // Get the buffer sizes needed to hold the active paths and the source/target mode table. Win32Utilities.ThrowIfResultCodeNotSuccess( CCD.GetDisplayConfigBufferSizes( OnlyActivePathsFlag, out numPathArrayElements, out numModeInfoArrayElements)); CCD.DisplayConfigPathInfo[] pathInfoArray = new CCD.DisplayConfigPathInfo[numPathArrayElements]; CCD.DisplayConfigModeInfo[] modeInfoArray = new CCD.DisplayConfigModeInfo[numModeInfoArrayElements]; // Get the active paths and their associated source/target modes. Win32Utilities.ThrowIfResultCodeNotSuccess( CCD.QueryDisplayConfig( OnlyActivePathsFlag, ref numPathArrayElements, pathInfoArray, ref numModeInfoArrayElements, modeInfoArray, IntPtr.Zero)); displayPreset = new DisplayPreset(presetName); displayPreset.PathInfoArray = pathInfoArray; displayPreset.ModeInfoArray = modeInfoArray; // Save the Target Device Name structs to log the monitor output devices. This isn't // actually used for anything but makes the XML output more readable. CCD.DisplayConfigTargetDeviceName[] targetDeviceNameArray = new CCD.DisplayConfigTargetDeviceName[pathInfoArray.Length]; for (int i = 0; i < pathInfoArray.Length; i++) { targetDeviceNameArray[i] = GetTargetDeviceName(pathInfoArray[i].targetInfo.adapterId, pathInfoArray[i].targetInfo.id); } displayPreset.TargetDeviceNames = targetDeviceNameArray; // Save the Adapter Name structs. The adapter ID values may change on reboot, as they // appear to simply be a logical, run-time value rather than a persistent identifier. // So we save the Adapter Name structs to log a device name that the adapter ID maps to. // We can use this to update the adapter IDs we save in our presets such that the presets // will still be usable after a reboot. Otherwise, when the machine is rebooted and the // user tries to apply a saved preset, the API call will fail because the adapter ID has // changed. Dictionary <CCD.LUID, CCD.DisplayConfigAdapterName> adapterIdToAdapterName = new Dictionary <CCD.LUID, CCD.DisplayConfigAdapterName>(); // Find all the unique adapter IDs used in the active paths and capture the display adapter // device names that those IDs map to. foreach (CCD.DisplayConfigPathInfo pathInfo in pathInfoArray) { if (!adapterIdToAdapterName.ContainsKey(pathInfo.sourceInfo.adapterId)) { CCD.DisplayConfigAdapterName adapterName = new CCD.DisplayConfigAdapterName(); adapterName.header.adapterId = pathInfo.sourceInfo.adapterId; adapterName.header.size = (uint)System.Runtime.InteropServices.Marshal.SizeOf(adapterName); adapterName.header.type = CCD.DisplayConfigDeviceInfoType.GetAdapterName; Win32Utilities.ThrowIfResultCodeNotSuccess(CCD.DisplayConfigGetDeviceInfo(ref adapterName)); adapterIdToAdapterName.Add(adapterName.header.adapterId, adapterName); } } displayPreset.AdapterNames = adapterIdToAdapterName.Values.ToArray(); return(displayPreset); }