diff --git a/src/System.Windows.Forms/src/PublicAPI.Shipped.txt b/src/System.Windows.Forms/src/PublicAPI.Shipped.txt index 3f768c490c2..89d81e41b4a 100644 --- a/src/System.Windows.Forms/src/PublicAPI.Shipped.txt +++ b/src/System.Windows.Forms/src/PublicAPI.Shipped.txt @@ -3320,6 +3320,7 @@ static System.Windows.Forms.VisualStyles.VisualStyleInformation.Url.get -> strin static System.Windows.Forms.VisualStyles.VisualStyleInformation.Version.get -> string! static System.Windows.Forms.VisualStyles.VisualStyleRenderer.IsElementDefined(System.Windows.Forms.VisualStyles.VisualStyleElement! element) -> bool static System.Windows.Forms.VisualStyles.VisualStyleRenderer.IsSupported.get -> bool +static System.Windows.Forms.VisualStyles.VisualStyleRenderer.IsDarkModeSupported.get -> bool static System.Windows.Forms.WindowsFormsSynchronizationContext.AutoInstall.get -> bool static System.Windows.Forms.WindowsFormsSynchronizationContext.AutoInstall.set -> void static System.Windows.Forms.WindowsFormsSynchronizationContext.Uninstall() -> void diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Application.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Application.cs index 77285629a6b..b4893177962 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Application.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Application.cs @@ -48,8 +48,6 @@ public sealed partial class Application private static SystemColorMode? s_colorMode; #pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. - private const string DarkModeKeyPath = "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; - private const string DarkModeKey = "AppsUseLightTheme"; private const int SystemDarkModeDisabled = 1; /// @@ -379,21 +377,9 @@ private static int GetSystemColorModeInternal() return SystemDarkModeDisabled; } - int systemColorMode = SystemDarkModeDisabled; - - try - { - // 0 for dark mode and |1| for light mode. - systemColorMode = Math.Abs((Registry.GetValue( - keyName: DarkModeKeyPath, - valueName: DarkModeKey, - defaultValue: SystemDarkModeDisabled) as int?) ?? systemColorMode); - } - catch (Exception ex) when (!ex.IsCriticalException()) - { - } - - return systemColorMode; +#pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + return VisualStyleRenderer.IsDarkModeSupported ? 0 : 1; +#pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. } private static bool IsSystemDarkModeAvailable => diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Control.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Control.cs index eea81eb8fbc..0fa2de86f4d 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Control.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Control.cs @@ -163,7 +163,8 @@ public unsafe partial class Control : internal const string ExplorerThemeIdentifier = "Explorer"; internal const string ItemsViewThemeIdentifier = "ItemsView"; internal const string ComboBoxButtonThemeIdentifier = "CFD"; - + internal const string BannerContainerThemeIdentifier = "FileExplorerBannerContainer"; + internal const string NavPaneThemeIdentifier = "ExplorerNavPane"; private const short PaintLayerBackground = 1; private const short PaintLayerForeground = 2; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ComboBox/ComboBoxRenderer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ComboBox/ComboBoxRenderer.cs index af1b1c9ff11..0147f232fd2 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ComboBox/ComboBoxRenderer.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ComboBox/ComboBoxRenderer.cs @@ -14,7 +14,11 @@ public static class ComboBoxRenderer // Make this per-thread, so that different threads can safely use these methods. [ThreadStatic] private static VisualStyleRenderer? t_visualStyleRenderer; - private static readonly VisualStyleElement s_comboBoxElement = VisualStyleElement.ComboBox.DropDownButton.Normal; +#pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + private static readonly VisualStyleElement s_comboBoxElement = Application.IsDarkModeEnabled + ? VisualStyleElement.CreateElement($"{Control.DarkModeIdentifier}_{Control.ComboBoxButtonThemeIdentifier}::COMBOBOX", 1, 1) + : VisualStyleElement.ComboBox.DropDownButton.Normal; +#pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. private static readonly VisualStyleElement s_textBoxElement = VisualStyleElement.TextBox.TextEdit.Normal; /// diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewButtonCell.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewButtonCell.cs index d1d5af1608c..ae9207af716 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewButtonCell.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewButtonCell.cs @@ -17,7 +17,11 @@ public partial class DataGridViewButtonCell : DataGridViewCell private static readonly int s_propButtonCellFlatStyle = PropertyStore.CreateKey(); private static readonly int s_propButtonCellState = PropertyStore.CreateKey(); private static readonly int s_propButtonCellUseColumnTextForButtonValue = PropertyStore.CreateKey(); - private static readonly VisualStyleElement s_buttonElement = VisualStyleElement.Button.PushButton.Normal; +#pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + private static readonly VisualStyleElement s_darkButtonElement = VisualStyleElement.CreateElement("DarkMode_Explorer::BUTTON", 1, 1); + private static readonly VisualStyleElement s_lightButtonElement = VisualStyleElement.Button.PushButton.Normal; + private static readonly VisualStyleElement s_buttonElement = Application.IsDarkModeEnabled ? s_darkButtonElement : s_lightButtonElement; +#pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. private const byte DATAGRIDVIEWBUTTONCELL_themeMargin = 100; // Used to calculate the margins required for theming rendering private const byte DATAGRIDVIEWBUTTONCELL_horizontalTextMargin = 2; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewCheckBoxCell.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewCheckBoxCell.cs index 1148a0e5f11..957cddf5261 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewCheckBoxCell.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewCheckBoxCell.cs @@ -20,7 +20,14 @@ public partial class DataGridViewCheckBoxCell : DataGridViewCell, IDataGridViewE private const DataGridViewContentAlignment AnyBottom = DataGridViewContentAlignment.BottomRight | DataGridViewContentAlignment.BottomCenter | DataGridViewContentAlignment.BottomLeft; private const DataGridViewContentAlignment AnyMiddle = DataGridViewContentAlignment.MiddleRight | DataGridViewContentAlignment.MiddleCenter | DataGridViewContentAlignment.MiddleLeft; - private static readonly VisualStyleElement s_checkBoxElement = VisualStyleElement.Button.CheckBox.UncheckedNormal; +#pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + private static readonly VisualStyleElement s_darkCheckBoxElement = VisualStyleElement.CreateElement($"{Control.DarkModeIdentifier}_{Control.ExplorerThemeIdentifier}::BUTTON", 3, 1); + private static readonly VisualStyleElement s_lightCheckBoxElement = VisualStyleElement.Button.CheckBox.UncheckedNormal; + private static readonly VisualStyleElement s_checkBoxElement = Application.IsDarkModeEnabled + ? s_darkCheckBoxElement + : s_lightCheckBoxElement; +#pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + private static readonly int s_propButtonCellState = PropertyStore.CreateKey(); private static readonly int s_propTrueValue = PropertyStore.CreateKey(); private static readonly int s_propFalseValue = PropertyStore.CreateKey(); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewColumnHeaderCell.DataGridViewColumnHeaderCellRenderer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewColumnHeaderCell.DataGridViewColumnHeaderCellRenderer.cs index 47a8fd77cac..b3957afe13e 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewColumnHeaderCell.DataGridViewColumnHeaderCellRenderer.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewColumnHeaderCell.DataGridViewColumnHeaderCellRenderer.cs @@ -16,7 +16,11 @@ public static VisualStyleRenderer VisualStyleRenderer { get { - s_visualStyleRenderer ??= new VisualStyleRenderer(s_headerElement); +#pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + s_visualStyleRenderer ??= new VisualStyleRenderer(Application.IsDarkModeEnabled + ? VisualStyleElement.CreateElement($"{Control.DarkModeIdentifier}_{Control.ItemsViewThemeIdentifier}::Header", 1, 1) + : VisualStyleElement.Header.Item.Normal); +#pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. return s_visualStyleRenderer; } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewColumnHeaderCell.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewColumnHeaderCell.cs index 2b62f13986f..3cec23dbcd5 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewColumnHeaderCell.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewColumnHeaderCell.cs @@ -11,7 +11,11 @@ namespace System.Windows.Forms; public partial class DataGridViewColumnHeaderCell : DataGridViewHeaderCell { - private static readonly VisualStyleElement s_headerElement = VisualStyleElement.Header.Item.Normal; +#pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + private static readonly VisualStyleElement s_headerElement = Application.IsDarkModeEnabled + ? VisualStyleElement.CreateElement($"{Control.DarkModeIdentifier}_{Control.ItemsViewThemeIdentifier}::Header", 1, 1) + : VisualStyleElement.Header.Item.Normal; +#pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. private const byte SortGlyphSeparatorWidth = 2; // additional 2 pixels between caption and glyph private const byte SortGlyphHorizontalMargin = 4; // 4 pixels on left & right of glyph diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewComboBoxCell.DataGridViewComboBoxCellRenderer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewComboBoxCell.DataGridViewComboBoxCellRenderer.cs index 7c5cf83af53..3cf2fd860b9 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewComboBoxCell.DataGridViewComboBoxCellRenderer.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewComboBoxCell.DataGridViewComboBoxCellRenderer.cs @@ -12,10 +12,29 @@ private static class DataGridViewComboBoxCellRenderer { [ThreadStatic] private static VisualStyleRenderer? t_visualStyleRenderer; - private static readonly VisualStyleElement s_comboBoxBorder = VisualStyleElement.ComboBox.Border.Normal; - private static readonly VisualStyleElement s_comboBoxDropDownButtonRight = VisualStyleElement.ComboBox.DropDownButtonRight.Normal; - private static readonly VisualStyleElement s_comboBoxDropDownButtonLeft = VisualStyleElement.ComboBox.DropDownButtonLeft.Normal; - private static readonly VisualStyleElement s_comboBoxReadOnlyButton = VisualStyleElement.ComboBox.ReadOnlyButton.Normal; +#pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + private static readonly VisualStyleElement s_comboBoxBorder = Application.IsDarkModeEnabled + ? VisualStyleElement.CreateElement($"{Control.DarkModeIdentifier}_{Control.ComboBoxButtonThemeIdentifier}::COMBOBOX", 4, 1) + : VisualStyleElement.ComboBox.Border.Normal; +#pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + +#pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + private static readonly VisualStyleElement s_comboBoxDropDownButtonRight = Application.IsDarkModeEnabled + ? VisualStyleElement.CreateElement($"{Control.DarkModeIdentifier}_{Control.ComboBoxButtonThemeIdentifier}::COMBOBOX", 6, 1) + : VisualStyleElement.ComboBox.DropDownButtonRight.Normal; +#pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + +#pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + private static readonly VisualStyleElement s_comboBoxDropDownButtonLeft = Application.IsDarkModeEnabled + ? VisualStyleElement.CreateElement($"{Control.DarkModeIdentifier}_{Control.ComboBoxButtonThemeIdentifier}::COMBOBOX", 7, 1) + : VisualStyleElement.ComboBox.DropDownButtonLeft.Normal; +#pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + +#pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + private static readonly VisualStyleElement s_comboBoxReadOnlyButton = Application.IsDarkModeEnabled + ? VisualStyleElement.CreateElement($"{Control.DarkModeIdentifier}_{Control.ComboBoxButtonThemeIdentifier}::COMBOBOX", 5, 1) + : VisualStyleElement.ComboBox.ReadOnlyButton.Normal; +#pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. public static VisualStyleRenderer VisualStyleRenderer { diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewRowHeaderCell.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewRowHeaderCell.cs index 0cb86c1a563..67e0cafbc87 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewRowHeaderCell.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewRowHeaderCell.cs @@ -11,7 +11,11 @@ namespace System.Windows.Forms; public partial class DataGridViewRowHeaderCell : DataGridViewHeaderCell { - private static readonly VisualStyleElement s_headerElement = VisualStyleElement.Header.Item.Normal; +#pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + private static readonly VisualStyleElement s_headerElement = Application.IsDarkModeEnabled + ? VisualStyleElement.CreateElement($"{Control.DarkModeIdentifier}_{Control.ItemsViewThemeIdentifier}::Header", 1, 1) + : VisualStyleElement.Header.Item.Normal; +#pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. private static Bitmap? s_rightArrowBmp; private static Bitmap? s_leftArrowBmp; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewTopLeftHeaderCell.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewTopLeftHeaderCell.cs index fd144424d4d..d3128a362f0 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewTopLeftHeaderCell.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewTopLeftHeaderCell.cs @@ -8,7 +8,11 @@ namespace System.Windows.Forms; public partial class DataGridViewTopLeftHeaderCell : DataGridViewColumnHeaderCell { - private static readonly VisualStyleElement s_headerElement = VisualStyleElement.Header.Item.Normal; +#pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + private static readonly VisualStyleElement s_headerElement = Application.IsDarkModeEnabled + ? VisualStyleElement.CreateElement($"{Control.DarkModeIdentifier}_{Control.ItemsViewThemeIdentifier}::Header", 1, 1) + : VisualStyleElement.Header.Item.Normal; +#pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. private const byte DATAGRIDVIEWTOPLEFTHEADERCELL_horizontalTextMarginLeft = 1; private const byte DATAGRIDVIEWTOPLEFTHEADERCELL_horizontalTextMarginRight = 2; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TabControl/TabControl.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TabControl/TabControl.cs index fdacf2dc94d..f8425159126 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TabControl/TabControl.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TabControl/TabControl.cs @@ -1259,6 +1259,13 @@ protected override void OnHandleCreated(EventArgs e) 0, 0, 0, 0, SET_WINDOW_POS_FLAGS.SWP_NOMOVE | SET_WINDOW_POS_FLAGS.SWP_NOSIZE | SET_WINDOW_POS_FLAGS.SWP_NOACTIVATE); } + +#pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + if (Application.IsDarkModeEnabled) + { + PInvoke.SendMessage(tooltipHwnd, PInvoke.TTM_SETWINDOWTHEME, default, "DarkMode_Explorer"); + } +#pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. } // Add the pages @@ -1288,6 +1295,17 @@ protected override void OnHandleCreated(EventArgs e) } UpdateTabSelection(false); + // TabControl didn't have Tab Appearance in Dark mode theme to support Dark Mode Tab Appearance we need to draw The buttons in paint event. + +#pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + if (Application.IsDarkModeEnabled && GetStyle(ControlStyles.ApplyThemingImplicitly)) + { + _ = PInvoke.SetWindowTheme( + hwnd: HWND, + pszSubAppName: null, + pszSubIdList: $"{DarkModeIdentifier}::{BannerContainerThemeIdentifier}"); + } +#pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. } protected override void OnHandleDestroyed(EventArgs e) diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TabControl/TabRenderer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TabControl/TabRenderer.cs index 866aa65da29..3bf92035501 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TabControl/TabRenderer.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TabControl/TabRenderer.cs @@ -3,7 +3,6 @@ using System.Drawing; using System.Windows.Forms.VisualStyles; - namespace System.Windows.Forms; /// @@ -144,7 +143,16 @@ public static void DrawTabPage(Graphics g, Rectangle bounds) internal static void DrawTabPage(IDeviceContext deviceContext, Rectangle bounds) { - InitializeRenderer(VisualStyleElement.Tab.Pane.Normal, 0); +#pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + // Using DarkMode Theme Subclass. + // see https://learn.microsoft.com/windows/win32/controls/theme-subclasses. + VisualStyleElement darkTabPaneElement = VisualStyleElement.CreateElement($"{Control.DarkModeIdentifier}::{Control.NavPaneThemeIdentifier}", 0, 0); + VisualStyleElement lightTabPaneElement = VisualStyleElement.Tab.Pane.Normal; + VisualStyleElement tabPaneElement = Application.IsDarkModeEnabled + ? darkTabPaneElement + : lightTabPaneElement; + InitializeRenderer(tabPaneElement, 0); +#pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. t_visualStyleRenderer.DrawBackground(deviceContext, bounds); } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/VisualStyles/VisualStyleRenderer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/VisualStyles/VisualStyleRenderer.cs index e4489b18673..749cb4281ad 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/VisualStyles/VisualStyleRenderer.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/VisualStyles/VisualStyleRenderer.cs @@ -3,6 +3,7 @@ using System.Drawing; using System.Drawing.Interop; +using System.Windows.Forms.Analyzers.Diagnostics; using Microsoft.Win32; namespace System.Windows.Forms.VisualStyles; @@ -65,6 +66,37 @@ public static bool IsSupported } } + /// + /// + /// Gets a value specifying whether the operating system has Dark Mode visual styles subclass and the Application can use this subclass to draw controls with Dark Mode theme. + /// + /// + /// + /// Returns true if Visual Style Dark Mode subclass is: + /// 1) Supported by the operating system. + /// 2) Enabled in the client area. + /// 3) operating system not ruining in high contrast mode + /// Otherwise, returns false. Note that if false is returned, attempts to create/use objects of this class will throw exceptions. + /// + /// + /// + [Experimental(DiagnosticIDs.ExperimentalDarkMode, UrlFormat = DiagnosticIDs.UrlFormat)] + public static bool IsDarkModeSupported + { + get + { + bool supported = AreClientAreaVisualStylesSupported; + + if (supported) + { + HTHEME hTheme = GetHandle($"{Control.DarkModeIdentifier}_{Control.ExplorerThemeIdentifier}::BUTTON", false); // Button is an arbitrary choice. + supported = !hTheme.IsNull && !SystemInformation.HighContrast; + } + + return supported; + } + } + /// /// Returns true if the element is defined by the current visual style, else false. /// Note: