public void RefreshDisplayDevices() { lock (display_lock) { // Store an array of the current available DisplayDevice objects. // This is needed to preserve the original resolution. var previousDevices = AvailableDevices.ToArray(); AvailableDevices.Clear(); // We save all necessary parameters in temporary variables // and construct the device when every needed detail is available. // The main DisplayDevice constructor adds the newly constructed device // to the list of available devices. DisplayDevice opentk_dev; DisplayResolution opentk_dev_current_res = null; var opentk_dev_available_res = new List <DisplayResolution>(); bool opentk_dev_primary = false; uint device_count = 0, mode_count = 0; // Get available video adapters and enumerate all monitors while (User32.DeviceContext.EnumDisplayDevices(null, device_count++, out var dev1, 0)) { if ((dev1.StateFlags & DisplayDeviceStateFlags.AttachedToDesktop) == 0) { continue; } // The second function should only be executed when the first one fails // (e.g. when the monitor is disabled) if (User32.DeviceContext.EnumDisplaySettingsEx(dev1.DeviceName, DisplayModeSetting.CurrentSettings, out DeviceMode monitor_mode, 0) || User32.DeviceContext.EnumDisplaySettingsEx(dev1.DeviceName, DisplayModeSetting.RegistrySettings, out monitor_mode, 0)) { VerifyMode(dev1, monitor_mode); var scale = GetScale(ref monitor_mode); opentk_dev_current_res = new DisplayResolution( (int)(monitor_mode.DisplayOptions.Position.X / scale), (int)(monitor_mode.DisplayOptions.Position.Y / scale), (int)(monitor_mode.WidthInPixels / scale), (int)(monitor_mode.HeightInPixels / scale), (int)monitor_mode.BitsPerPixel, monitor_mode.DisplayFrequency ); opentk_dev_primary = (dev1.StateFlags & DisplayDeviceStateFlags.PrimaryDevice) != 0; } opentk_dev_available_res.Clear(); mode_count = 0; while (User32.DeviceContext.EnumDisplaySettingsEx(dev1.DeviceName, (DisplayModeSetting)mode_count++, out monitor_mode, 0)) { VerifyMode(dev1, monitor_mode); var scale = GetScale(ref monitor_mode); var res = new DisplayResolution( (int)(monitor_mode.DisplayOptions.Position.X / scale), (int)(monitor_mode.DisplayOptions.Position.Y / scale), (int)(monitor_mode.WidthInPixels / scale), (int)(monitor_mode.HeightInPixels / scale), (int)monitor_mode.BitsPerPixel, monitor_mode.DisplayFrequency ); opentk_dev_available_res.Add(res); } // Construct the OpenTK DisplayDevice through the accumulated parameters. // The constructor will automatically add the DisplayDevice to the list // of available devices. #pragma warning disable 612,618 opentk_dev = new DisplayDevice( opentk_dev_current_res, opentk_dev_primary, opentk_dev_available_res, opentk_dev_current_res.Bounds, dev1.DeviceName ); #pragma warning restore 612,618 // Set the original resolution if the DisplayDevice was previously available. foreach (var existingDevice in previousDevices) { if ((string)existingDevice.Id == (string)opentk_dev.Id) { opentk_dev.OriginalResolution = existingDevice.OriginalResolution; } } AvailableDevices.Add(opentk_dev); if (opentk_dev_primary) { Primary = opentk_dev; } Debug.Print("DisplayDevice {0} ({1}) supports {2} resolutions.", device_count, opentk_dev.IsPrimary ? "primary" : "secondary", opentk_dev.AvailableResolutions.Count); } } }