diff --git a/src/System.Drawing.Common/src/System/Drawing/Graphics_Async.cs b/src/System.Drawing.Common/src/System/Drawing/Graphics_Async.cs new file mode 100644 index 00000000000..58eeb15d2bf --- /dev/null +++ b/src/System.Drawing.Common/src/System/Drawing/Graphics_Async.cs @@ -0,0 +1,91 @@ +using System.ComponentModel; +using System.Threading.Tasks; + +namespace System.Drawing; + +public sealed unsafe partial class Graphics +{ + /// + /// Creates a Graphics object from a handle asynchronously. + /// + /// The handle to the device context. + /// + /// A task that represents the asynchronous operation. + /// The task result contains the created Graphics object. + /// + [EditorBrowsable(EditorBrowsableState.Advanced)] + public static Task FromHwndAsync(IntPtr handle) + { + TaskCompletionSource tcs = new TaskCompletionSource(); + + try + { + Graphics graphics = Graphics.FromHwnd(handle); + tcs.TrySetResult(graphics); + } + catch (Exception ex) + { + tcs.TrySetException(ex); + } + + return tcs.Task; + } + + /// + /// Creates a Graphics object from a handle asynchronously, with a specified thread-confining bounds. + /// + /// The handle to the device context. + /// The thread-confining bounds for the Graphics object. + /// + /// A task that represents the asynchronous operation. + /// The task result contains the created Graphics object. + /// + [EditorBrowsable(EditorBrowsableState.Advanced)] + public static Task FromHwndAsync(IntPtr handle, RectangleF threadConfiningBounds) + { + TaskCompletionSource tcs = new TaskCompletionSource(); + + try + { + Graphics graphics = Graphics.FromHwnd(handle); + graphics.TranslateTransform(threadConfiningBounds.X, threadConfiningBounds.Y); + graphics.SetClip(new RectangleF(PointF.Empty, threadConfiningBounds.Size)); + tcs.TrySetResult(graphics); + } + catch (Exception ex) + { + tcs.SetException(ex); + } + + return tcs.Task; + } + + /// + /// Creates a Graphics object from a handle asynchronously, with a specified thread-confining bounds. + /// + /// The handle to the device context. + /// The thread-confining bounds for the Graphics object. + /// + /// A task that represents the asynchronous operation. + /// The task result contains the created Graphics object. + /// + [EditorBrowsable(EditorBrowsableState.Advanced)] + public static Task FromHwndAsync(IntPtr handle, Rectangle threadConfiningBounds) + { + TaskCompletionSource tcs = new TaskCompletionSource(); + + try + { + Graphics graphics = Graphics.FromHwnd(handle); + graphics.TranslateTransform(threadConfiningBounds.X, threadConfiningBounds.Y); + graphics.SetClip(new RectangleF(PointF.Empty, threadConfiningBounds.Size)); + tcs.TrySetResult(graphics); + } + catch (Exception ex) + { + tcs.SetException(ex); + } + + return tcs.Task; + } +} diff --git a/src/System.Drawing.Common/src/System/Drawing/SystemPens.cs b/src/System.Drawing.Common/src/System/Drawing/SystemPens.cs index 8e1786d5fac..83578acf917 100644 --- a/src/System.Drawing.Common/src/System/Drawing/SystemPens.cs +++ b/src/System.Drawing.Common/src/System/Drawing/SystemPens.cs @@ -3,6 +3,45 @@ namespace System.Drawing; +public static class SystemColorsRouter +{ + internal static Func s_activeBorderRouter = () => SystemColors.ActiveBorder; + + public static Color ActiveBorder => s_activeBorderRouter(); + public static Color ActiveCaption => SystemColors.ActiveCaption; + public static Color ActiveCaptionText => SystemColors.ActiveCaptionText; + public static Color AppWorkspace => SystemColors.AppWorkspace; + public static Color ButtonFace => SystemColors.ButtonFace; + public static Color ButtonHighlight => SystemColors.ButtonHighlight; + public static Color ButtonShadow => SystemColors.ButtonShadow; + public static Color Control => SystemColors.Control; + public static Color ControlDark => SystemColors.ControlDark; + public static Color ControlDarkDark => SystemColors.ControlDarkDark; + public static Color ControlLight => SystemColors.ControlLight; + public static Color ControlLightLight => SystemColors.ControlLightLight; + public static Color ControlText => SystemColors.ControlText; + public static Color Desktop => SystemColors.Desktop; + public static Color GradientActiveCaption => SystemColors.GradientActiveCaption; + public static Color GradientInactiveCaption => SystemColors.GradientInactiveCaption; + public static Color GrayText => SystemColors.GrayText; + public static Color Highlight => SystemColors.Highlight; + public static Color HighlightText => SystemColors.HighlightText; + public static Color HotTrack => SystemColors.HotTrack; + public static Color InactiveBorder => SystemColors.InactiveBorder; + public static Color InactiveCaption => SystemColors.InactiveCaption; + public static Color InactiveCaptionText => SystemColors.InactiveCaptionText; + public static Color Info => SystemColors.Info; + public static Color InfoText => SystemColors.InfoText; + public static Color Menu => SystemColors.Menu; + public static Color MenuBar => SystemColors.MenuBar; + public static Color MenuHighlight => SystemColors.MenuHighlight; + public static Color MenuText => SystemColors.MenuText; + public static Color ScrollBar => SystemColors.ScrollBar; + public static Color Window => SystemColors.Window; + public static Color WindowFrame => SystemColors.WindowFrame; + public static Color WindowText => SystemColors.WindowText; +} + public static class SystemPens { private static readonly object s_systemPensKey = new(); diff --git a/src/System.Windows.Forms.Primitives/src/NativeMethods.txt b/src/System.Windows.Forms.Primitives/src/NativeMethods.txt index 6dc088f67e9..4ae02aaad4a 100644 --- a/src/System.Windows.Forms.Primitives/src/NativeMethods.txt +++ b/src/System.Windows.Forms.Primitives/src/NativeMethods.txt @@ -108,6 +108,8 @@ DSH_FLAGS DTM_* DTN_* DTS_* +DwmSetWindowAttribute +DWM_WINDOW_CORNER_PREFERENCE DuplicateHandle EC_* ECO_* @@ -164,6 +166,7 @@ GetClipboardFormatName GetClipBox GetClipCursor GetClipRgn +GetComboBoxInfo GetCurrentActCtx GetCurrentObject GetCurrentProcess diff --git a/src/System.Windows.Forms/src/GlobalSuppressions.cs b/src/System.Windows.Forms/src/GlobalSuppressions.cs index 3a05c106211..78b417923a8 100644 --- a/src/System.Windows.Forms/src/GlobalSuppressions.cs +++ b/src/System.Windows.Forms/src/GlobalSuppressions.cs @@ -196,7 +196,6 @@ [assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Thread local", Scope = "member", Target = "~F:System.Windows.Forms.ToolStripScrollButton.t_downScrollImage")] [assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Thread local", Scope = "member", Target = "~F:System.Windows.Forms.ToolStripSystemRenderer.t_renderer")] [assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Thread local", Scope = "member", Target = "~F:System.Windows.Forms.TrackBarRenderer.t_visualStyleRenderer")] -[assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Thread local", Scope = "member", Target = "~F:System.Windows.Forms.MessageBox.t_helpInfoTable")] [assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Thread local", Scope = "member", Target = "~F:System.Windows.Forms.ErrorProvider.t_defaultIcon")] [assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Thread local", Scope = "member", Target = "~F:System.Windows.Forms.DockingAttribute.Default")] [assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Thread local", Scope = "member", Target = "~F:System.Windows.Forms.NativeWindow.t_anyHandleCreated")] diff --git a/src/System.Windows.Forms/src/PublicAPI.Unshipped.txt b/src/System.Windows.Forms/src/PublicAPI.Unshipped.txt index e69de29bb2d..55503c58860 100644 --- a/src/System.Windows.Forms/src/PublicAPI.Unshipped.txt +++ b/src/System.Windows.Forms/src/PublicAPI.Unshipped.txt @@ -0,0 +1,117 @@ +override System.Windows.Forms.Popup.CreateParams.get -> System.Windows.Forms.CreateParams! +override System.Windows.Forms.Popup.WndProc(ref System.Windows.Forms.Message m) -> void +override System.Windows.Forms.ProgressBar.OnCreateControl() -> void +static System.Windows.Forms.Application.DefaultDarkMode.get -> System.Windows.Forms.DarkMode +static System.Windows.Forms.Application.EnvironmentDarkMode.get -> System.Windows.Forms.DarkMode +static System.Windows.Forms.Application.IsDarkModeEnabled.get -> bool +static System.Windows.Forms.Application.SetDefaultDarkMode(System.Windows.Forms.DarkMode darkMode) -> bool +static System.Windows.Forms.Application.SystemColors.get -> System.Windows.Forms.ThemedSystemColors! +static System.Windows.Forms.MessageBox.ShowAsync(string? text, string? caption = "", System.Windows.Forms.MessageBoxButtons buttons = System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon icon = System.Windows.Forms.MessageBoxIcon.None, System.Windows.Forms.MessageBoxDefaultButton defaultButton = System.Windows.Forms.MessageBoxDefaultButton.Button1, System.Windows.Forms.MessageBoxOptions options = System.Windows.Forms.MessageBoxOptions.DefaultDesktopOnly, System.Windows.Forms.IWin32Window? owner = null, string? helpFilePath = null, System.Windows.Forms.HelpNavigator navigator = (System.Windows.Forms.HelpNavigator)0, object? param = null) -> System.Threading.Tasks.Task! +static System.Windows.Forms.Popup.GetPopupLocation(System.Windows.Forms.Control! referringControl, System.Drawing.Size popupSize) -> System.Drawing.Point +System.Windows.Forms.AsyncGraphicsFactory +System.Windows.Forms.AsyncGraphicsFactory.GetGraphicsAsync() -> System.Threading.Tasks.Task! +System.Windows.Forms.Control.AsyncInvoke(System.Func!>! asyncFunc) -> T? +System.Windows.Forms.Control.DarkMode.get -> System.Windows.Forms.DarkMode +System.Windows.Forms.Control.DarkMode.set -> void +System.Windows.Forms.Control.InvokeAsync(System.Func! function, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +System.Windows.Forms.Control.InvokeAsync(System.Func!>! asyncFunc, T arg, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +System.Windows.Forms.Control.InvokeAsync(System.Func!>! asyncFunc, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +System.Windows.Forms.Control.InvokeSyncAsync(System.Func! syncFunction, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +System.Windows.Forms.DarkMode +System.Windows.Forms.DarkMode.Disabled = 3 -> System.Windows.Forms.DarkMode +System.Windows.Forms.DarkMode.Enabled = 2 -> System.Windows.Forms.DarkMode +System.Windows.Forms.DarkMode.Inherits = 1 -> System.Windows.Forms.DarkMode +System.Windows.Forms.DarkMode.NotSupported = 0 -> System.Windows.Forms.DarkMode +System.Windows.Forms.Form.SetWindowBorderColor(System.Drawing.Color color) -> void +System.Windows.Forms.Form.SetWindowCaptionColor(System.Drawing.Color color) -> void +System.Windows.Forms.Form.SetWindowCaptionTextColor(System.Drawing.Color color) -> void +System.Windows.Forms.Form.SetWindowCornerPreference(System.Windows.Forms.Form.WindowCornerPreference cornerPreference) -> void +System.Windows.Forms.Form.ShowDialogAsync() -> System.Threading.Tasks.Task! +System.Windows.Forms.Form.ShowDialogAsync(System.Windows.Forms.IWin32Window! owner) -> System.Threading.Tasks.Task! +System.Windows.Forms.Form.WindowCornerPreference +System.Windows.Forms.Form.WindowCornerPreference.Default = 0 -> System.Windows.Forms.Form.WindowCornerPreference +System.Windows.Forms.Form.WindowCornerPreference.DoNotRound = 1 -> System.Windows.Forms.Form.WindowCornerPreference +System.Windows.Forms.Form.WindowCornerPreference.Round = 2 -> System.Windows.Forms.Form.WindowCornerPreference +System.Windows.Forms.Form.WindowCornerPreference.RoundSmall = 3 -> System.Windows.Forms.Form.WindowCornerPreference +System.Windows.Forms.PaintEventArgs.GraphicsFactory.get -> System.Windows.Forms.AsyncGraphicsFactory! +System.Windows.Forms.Popup +System.Windows.Forms.Popup.CanResize.get -> bool +System.Windows.Forms.Popup.CanResize.set -> void +System.Windows.Forms.Popup.ClosePopup() -> void +System.Windows.Forms.Popup.IsOpen.get -> bool +System.Windows.Forms.Popup.OpenPopup(System.Windows.Forms.Control! associatingControl) -> void +System.Windows.Forms.Popup.Popup() -> void +System.Windows.Forms.Popup.PopupClosed -> System.EventHandler? +System.Windows.Forms.Popup.PopupCloseRequested -> System.Windows.Forms.PopupCloseRequestEventHandler? +System.Windows.Forms.Popup.PopupClosing -> System.EventHandler? +System.Windows.Forms.Popup.PopupContent.get -> System.Windows.Forms.Control? +System.Windows.Forms.Popup.PopupContent.set -> void +System.Windows.Forms.Popup.PopupOpened -> System.EventHandler? +System.Windows.Forms.Popup.PopupOpening -> System.EventHandler? +System.Windows.Forms.PopupCloseRequestEventArgs +System.Windows.Forms.PopupCloseRequestEventArgs.ClosingRequestOrigin.get -> System.Windows.Forms.PopupCloseRequestOrigin +System.Windows.Forms.PopupCloseRequestEventArgs.ClosingRequestOrigin.set -> void +System.Windows.Forms.PopupCloseRequestEventArgs.KeyData.get -> System.Windows.Forms.Keys +System.Windows.Forms.PopupCloseRequestEventArgs.KeyData.set -> void +System.Windows.Forms.PopupCloseRequestEventArgs.PopupCloseRequestEventArgs(System.Windows.Forms.PopupCloseRequestReason closeReason) -> void +System.Windows.Forms.PopupCloseRequestEventArgs.PopupCloseRequestEventArgs(System.Windows.Forms.PopupCloseRequestReason closingRequestReason, System.Windows.Forms.Keys keyData) -> void +System.Windows.Forms.PopupCloseRequestEventArgs.PopupClosingRequestReason.get -> System.Windows.Forms.PopupCloseRequestReason +System.Windows.Forms.PopupCloseRequestEventArgs.PopupClosingRequestReason.set -> void +System.Windows.Forms.PopupCloseRequestEventHandler +System.Windows.Forms.PopupCloseRequestOrigin +System.Windows.Forms.PopupCloseRequestOrigin.ExternalByUser = 0 -> System.Windows.Forms.PopupCloseRequestOrigin +System.Windows.Forms.PopupCloseRequestOrigin.InternalByComponent = 1 -> System.Windows.Forms.PopupCloseRequestOrigin +System.Windows.Forms.PopupCloseRequestReason +System.Windows.Forms.PopupCloseRequestReason.AppLostFocus = 1 -> System.Windows.Forms.PopupCloseRequestReason +System.Windows.Forms.PopupCloseRequestReason.CloseMethodInvoked = 2 -> System.Windows.Forms.PopupCloseRequestReason +System.Windows.Forms.PopupCloseRequestReason.ContentClicked = 3 -> System.Windows.Forms.PopupCloseRequestReason +System.Windows.Forms.PopupCloseRequestReason.Keyboard = 4 -> System.Windows.Forms.PopupCloseRequestReason +System.Windows.Forms.PopupCloseRequestReason.PopupLostFocus = 0 -> System.Windows.Forms.PopupCloseRequestReason +System.Windows.Forms.PopupOpeningEventArgs +System.Windows.Forms.PopupOpeningEventArgs.PopupOpeningEventArgs(bool cancel, System.Drawing.Size preferredNewSize) -> void +System.Windows.Forms.PopupOpeningEventArgs.PreferredNewSize.get -> System.Drawing.Size +System.Windows.Forms.PopupOpeningEventArgs.PreferredNewSize.set -> void +System.Windows.Forms.PopupOpeningEventArgs.PreventResizing.get -> bool +System.Windows.Forms.PopupOpeningEventArgs.PreventResizing.set -> void +System.Windows.Forms.ThemedSystemColors +System.Windows.Forms.ThemedSystemColors.ThemedSystemColors() -> void +System.Windows.Forms.ToolStrip.GetGraphicsForItemAsync(System.Windows.Forms.ToolStripItem! toolStripItem) -> System.Threading.Tasks.Task! +virtual System.Windows.Forms.Control.DarkModeSupported.get -> bool +virtual System.Windows.Forms.Control.IsDarkModeEnabled.get -> bool +virtual System.Windows.Forms.Control.SetDarkModeCore(System.Windows.Forms.DarkMode darkModeSetting) -> bool +virtual System.Windows.Forms.Popup.OnPopupClosed(System.EventArgs! e) -> void +virtual System.Windows.Forms.Popup.OnPopupClosing(System.Windows.Forms.PopupCloseRequestEventArgs! e) -> void +virtual System.Windows.Forms.Popup.OnPopupOpening(System.Windows.Forms.PopupOpeningEventArgs! e) -> void +virtual System.Windows.Forms.ThemedSystemColors.ActiveBorder.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.ActiveCaption.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.ActiveCaptionText.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.AppWorkspace.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.ButtonFace.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.ButtonHighlight.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.ButtonShadow.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.Control.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.ControlDark.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.ControlDarkDark.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.ControlLight.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.ControlLightLight.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.ControlText.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.Desktop.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.GradientActiveCaption.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.GradientInactiveCaption.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.GrayText.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.Highlight.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.HighlightText.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.HotTrack.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.InactiveBorder.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.InactiveCaption.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.InactiveCaptionText.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.Info.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.InfoText.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.Menu.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.MenuBar.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.MenuHighlight.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.MenuText.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.ScrollBar.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.Window.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.WindowFrame.get -> System.Drawing.Color +virtual System.Windows.Forms.ThemedSystemColors.WindowText.get -> System.Drawing.Color diff --git a/src/System.Windows.Forms/src/System.Windows.Forms.csproj b/src/System.Windows.Forms/src/System.Windows.Forms.csproj index b26df9ea0b8..da19bbca235 100644 --- a/src/System.Windows.Forms/src/System.Windows.Forms.csproj +++ b/src/System.Windows.Forms/src/System.Windows.Forms.csproj @@ -81,4 +81,10 @@ PreserveNewest + + + + Component + + \ No newline at end of file diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/AxHost.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/AxHost.cs index d9b1249e73d..485a80b2d0d 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/AxHost.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/AxHost.cs @@ -3361,8 +3361,8 @@ private unsafe bool QuickActivate() } else { - qaContainer.colorFore = GetOleColorFromColor(SystemColors.WindowText); - qaContainer.colorBack = GetOleColorFromColor(SystemColors.Window); + qaContainer.colorFore = GetOleColorFromColor(Application.SystemColors.WindowText); + qaContainer.colorBack = GetOleColorFromColor(Application.SystemColors.Window); } qaContainer.dwAmbientFlags = QACONTAINERFLAGS.QACONTAINER_AUTOCLIP 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 bbcb3a3f87a..1d1ce3a842f 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Application.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Application.cs @@ -40,6 +40,11 @@ public sealed partial class Application private static readonly object s_internalSyncObject = new(); private static bool s_useWaitCursor; + private static DarkMode? s_darkMode; + + private const string DarkModeKeyPath = "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; + private const string DarkModeKey = "AppsUseLightTheme"; + /// /// Events the user can hook into /// @@ -52,7 +57,6 @@ public sealed partial class Application // Used to avoid recursive exit private static bool s_exiting; - private static bool s_parkingWindowCreated; /// @@ -234,13 +238,112 @@ public static InputLanguage CurrentInputLanguage internal static bool CustomThreadExceptionHandlerAttached => ThreadContext.FromCurrent().CustomThreadExceptionHandlerAttached; - internal static Font? DefaultFont => s_defaultFontScaled ?? s_defaultFont; + public static DarkMode DefaultDarkMode + { + get + { + if (!s_darkMode.HasValue) + { + if (EnvironmentDarkMode is DarkMode.NotSupported) + { + return DarkMode.NotSupported; + } + + return DarkMode.Disabled; + } + + return s_darkMode.Value; + } + } + + public static bool SetDefaultDarkMode(DarkMode darkMode) => darkMode switch + { + DarkMode.Enabled or + DarkMode.Disabled or + DarkMode.Inherits => SetDefaultDarkModeCore(darkMode), + + _ => throw new ArgumentException($"{darkMode} is not supported in this context.") + }; + + private static bool SetDefaultDarkModeCore(DarkMode darkMode) + { + if (EnvironmentDarkMode == DarkMode.NotSupported) + { + s_darkMode = DarkMode.NotSupported; + return false; + } + + s_darkMode = darkMode; + return true; + } + + internal static Font DefaultFont => s_defaultFontScaled ?? s_defaultFont!; + + public static DarkMode EnvironmentDarkMode + { + get + { + int systemDarkMode = -1; + + if (SystemInformation.HighContrast) + { + return DarkMode.NotSupported; + } + + // Dark mode is supported when we are >= W11/22000 + // Technically, we could go earlier, but then the APIs we're using weren't officially public. + if (OsVersion.IsWindows11_OrGreater()) + { + try + { + systemDarkMode = (int)(Registry.GetValue( + keyName: DarkModeKeyPath, + valueName: DarkModeKey, + defaultValue: -1) ?? 0); + } + catch + { + } + } + + return systemDarkMode switch + { + 0 => DarkMode.Enabled, + 1 => DarkMode.Disabled, + _ => DarkMode.NotSupported + }; + } + } + + /// + /// Gets a value indicating whether the application is running in a dark mode context. + /// Note: We're never using dark mode in a high contrast context. + /// + public static bool IsDarkModeEnabled => !SystemInformation.HighContrast + && DefaultDarkMode switch + { + DarkMode.Enabled => true, + DarkMode.Disabled => false, + _ => EnvironmentDarkMode switch + { + DarkMode.Enabled => true, + DarkMode.Disabled => false, + + // We return false even if DarkMode is not supported so that we ALWAYS have a valid result here. + _ => false + } + }; + + public static ThemedSystemColors SystemColors + => IsDarkModeEnabled + ? DarkThemedSystemColors.DefaultInstance + : LightThemedSystemColors.DefaultInstance; /// /// Gets the path for the executable file that started the application. /// - public static string ExecutablePath => - s_executablePath ??= PInvoke.GetModuleFileNameLongPath(HINSTANCE.Null); + public static string ExecutablePath + => s_executablePath ??= PInvoke.GetModuleFileNameLongPath(HINSTANCE.Null); /// /// Gets the current mode for the process. 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 a2a345ccd0b..049e0107cf9 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Control.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Control.cs @@ -14,6 +14,7 @@ using Windows.Win32.System.Ole; using Windows.Win32.UI.Accessibility; using Windows.Win32.UI.Input.KeyboardAndMouse; +using Windows.Win32.Graphics.Dwm; using Com = Windows.Win32.System.Com; using ComTypes = System.Runtime.InteropServices.ComTypes; using Encoding = System.Text.Encoding; @@ -218,6 +219,7 @@ public unsafe partial class Control : private static readonly int s_dataContextProperty = PropertyStore.CreateKey(); private static bool s_needToLoadComCtl = true; + private static readonly int s_darkModeProperty = PropertyStore.CreateKey(); // This switch determines the default text rendering engine to use by some controls that support switching rendering engine. // CheckedListBox, PropertyGrid, GroupBox, Label and LinkLabel, and ButtonBase controls. @@ -1707,11 +1709,110 @@ public ControlBindingsCollection DataBindings } } + /// + /// Gets or sets the dark mode for the control. + /// + /// + /// The dark mode for the control. The default value is . This property is ambient. + /// Deriving classes should override to implement their own dark-mode detection logic. + /// + public DarkMode DarkMode + { + get + { + if (Properties.ContainsObject(s_darkModeProperty)) + { + return (DarkMode)Properties.GetObject(s_darkModeProperty)!; + } + + return ParentInternal?.DarkMode ?? DarkMode.Inherits; + } + + set => SetDarkMode(value); + } + + private bool ShouldSerializeDarkMode() + => DarkMode != DefaultDarkMode; + + private void ResetDarkMode() + => DarkMode = DefaultDarkMode; + + /// + /// Tests, if the control is currently in dark mode. This property is ambient. Inherited controls can return false, + /// to prevent their base classes to apply their dark-mode logic, and can still test for dark-mode by calling base.IsDarkModeEnabled. + /// + protected virtual bool IsDarkModeEnabled + { + get + { + if (Properties.ContainsObject(s_darkModeProperty)) + { + // If we inherit, it's the parent's dark-mode, otherwise it's the value we have. + return (DarkMode == DarkMode.Inherits + && (ParentInternal?.IsDarkModeEnabled ?? false)) + || DarkMode == DarkMode.Enabled; + } + else + { + // We're ambient: It's either the parent's or the application's dark-mode. + return ParentInternal?.IsDarkModeEnabled ?? Application.IsDarkModeEnabled; + } + } + } + + private void SetDarkMode(DarkMode darkMode) + { + if (Equals(darkMode, DarkMode)) + { + return; + } + + if (darkMode switch + { + DarkMode.Inherits or + DarkMode.Enabled or + DarkMode.Disabled => Application.EnvironmentDarkMode == DarkMode.NotSupported || !DarkModeSupported + ? throw new ArgumentException("${darkModeSetting} is not supported in this Environment.") + : true, + _ => throw new ArgumentException("${darkModeSetting} is not supported in this context.") + }) + { + // When DarkModeSetting was different than its parent before, but now it is about to become the same, + // we're removing it altogether, so it can inherit the value from its parent. + if (Properties.ContainsObject(s_darkModeProperty) && Equals(ParentInternal?.DarkMode, darkMode)) + { + Properties.RemoveObject(s_darkModeProperty); + } + else + { + Properties.SetObject(s_darkModeProperty, darkMode); + } + + SetDarkModeCore(darkMode); + } + } + + /// + /// Inherited classes should override this method to implement their own dark-mode changed logic, if they need it. + /// + /// A value of type with the new dark-mode setting. + /// , if the setting succeeded, otherwise . + protected virtual bool SetDarkModeCore(DarkMode darkModeSetting) => true; + + /// + /// Determines whether the control supports dark mode. + /// + /// , if the control supports dark mode; otherwise, . + protected virtual bool DarkModeSupported + => Application.EnvironmentDarkMode != DarkMode.NotSupported; + + private static DarkMode DefaultDarkMode => DarkMode.Inherits; + /// /// The default BackColor of a generic top-level Control. Subclasses may have /// different defaults. /// - public static Color DefaultBackColor => SystemColors.Control; + public static Color DefaultBackColor => Application.SystemColors.Control; /// /// Deriving classes can override this to configure a default cursor for their control. @@ -1742,7 +1843,7 @@ public static Font DefaultFont /// The default ForeColor of a generic top-level Control. Subclasses may have /// different defaults. /// - public static Color DefaultForeColor => SystemColors.ControlText; + public static Color DefaultForeColor => Application.SystemColors.ControlText; protected virtual Padding DefaultMargin => CommonProperties.DefaultMargin; @@ -1788,7 +1889,7 @@ internal Color DisabledColor if (control is null) { // Don't know what to do, this seems good as anything - color = SystemColors.Control; + color = Application.SystemColors.Control; break; } @@ -7662,6 +7763,59 @@ protected virtual void OnHandleCreated(EventArgs e) PInvoke.SetWindowText(this, _text); } + if (IsDarkModeEnabled) + { + if (this is + + // Controls with 4 levels of inheritance, sorted alphabetically by type name + DomainUpDown // Inherits from UpDownBase, ContainerControl, ScrollableControl, Control + or NumericUpDown // Inherits from UpDownBase, ContainerControl, ScrollableControl, Control + + // Controls with 3 levels of inheritance, sorted alphabetically by type name + or CheckedListBox // Inherits from ListBox, ListControl, Control + or Form // Excluded - too invasive. + or FlowLayoutPanel // Inherits from Panel, ScrollableControl, Control + or SplitContainer // Inherits from ContainerControl, ScrollableControl, Control + or TabPage // Inherits from Panel, ScrollableControl, Control + or TableLayoutPanel // Inherits from Panel, ScrollableControl, Control + + // Controls with 2 levels of inheritance, sorted alphabetically by type name + // or ComboBox // Excluded - directly handled. + or ListBox // Inherits from ListControl, Control + + or Button // Inherits from ButtonBase, Control + or CheckBox // Inherits from ButtonBase, Control + or MaskedTextBox // Inherits from TextBoxBase, Control + or Panel // Inherits from ScrollableControl, Control + or RadioButton // Inherits from ButtonBase, Control + or RichTextBox // Inherits from TextBoxBase, Control + or TextBox // Inherits from TextBoxBase, Control + or HScrollBar // Inherits from ScrollBar, Control + or VScrollBar // Inherits from ScrollBar, Control + + // Base classes and controls with direct inheritance from Control, sorted alphabetically by type name + or ButtonBase // Inherits from Control + or DateTimePicker // Inherits from Control + // or GroupBox // Inherits from Control directly, but behaves like a container + or Label // Inherits from Control + or LinkLabel // Inherits from Label, Control + // or ListView // Excluded - directly handled. + or MonthCalendar // Inherits from Control + or PictureBox // Inherits from Control + or ProgressBar // Inherits from Control + or ScrollableControl // Inherits from Control + // or TextBoxBase // Excluded - probably too invasive. + or TrackBar // Inherits from Control + or TreeView // Inherits from Control + or UpDownBase) // Inherits from Control + + // Base class for all UI controls in WinForms + // or Control // Excluded. + { + _ = PInvoke.SetWindowTheme(HWND, "DarkMode_Explorer", null); + } + } + if (this is not ScrollableControl && !IsMirrored && GetExtendedState(ExtendedStates.SetScrollPosition) @@ -8560,7 +8714,7 @@ internal unsafe void PaintTransparentBackground(PaintEventArgs e, Rectangle rect // For whatever reason, our parent can't paint our background, but we need some kind of background // since we're transparent. using DeviceContextHdcScope hdcNoParent = new(e); - using CreateBrushScope hbrush = new(SystemColors.Control); + using CreateBrushScope hbrush = new(Application.SystemColors.Control); hdcNoParent.FillRectangle(rectangle, hbrush); return; } @@ -10699,8 +10853,19 @@ private protected void SetTopLevelInternal(bool value) CreateControl(); } - UpdateRoot(); + UpdateRoot(); + } } + + private static unsafe void PrepareDarkMode(HWND hwnd, bool darkModeEnabled) + { + BOOL value = darkModeEnabled; + + PInvoke.DwmSetWindowAttribute( + hwnd, + DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, + &value, + (uint)sizeof(BOOL)); } protected virtual void SetVisibleCore(bool value) @@ -10720,7 +10885,12 @@ protected virtual void SetVisibleCore(bool value) // bit and call CreateControl() if (IsHandleCreated || value) { - PInvoke.ShowWindow(this, value ? ShowParams : SHOW_WINDOW_CMD.SW_HIDE); + if (value) + { + PrepareDarkMode(HWND, IsDarkModeEnabled); + } + + PInvoke.ShowWindow(HWND, value ? ShowParams : SHOW_WINDOW_CMD.SW_HIDE); } } else if (IsHandleCreated || (value && _parent?.Created == true)) diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Control.Annotated.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Control_Annotated.cs similarity index 100% rename from src/System.Windows.Forms/src/System/Windows/Forms/Control.Annotated.cs rename to src/System.Windows.Forms/src/System/Windows/Forms/Control_Annotated.cs diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Control_InvokeAsync.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Control_InvokeAsync.cs new file mode 100644 index 00000000000..6628b7fc63c --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Control_InvokeAsync.cs @@ -0,0 +1,195 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.ExceptionServices; + +namespace System.Windows.Forms; + +public partial class Control +{ + /// + /// Executes an asynchronous function in a Task to avoid UI deadlocks, and blocks until the operation completes. + /// + /// The type of the result returned by the function. + /// The asynchronous function to execute. + /// The result of the asynchronous operation. + public T? AsyncInvoke(Func> asyncFunc) + { + ArgumentNullException.ThrowIfNull(asyncFunc); + + if (!IsHandleCreated) + { + throw new InvalidOperationException("Control handle not created."); + } + + // We need this to capture the result of the asynchronous operation. + // We don't run the passed task directly, because then we couldn't return the result synchronously. + // Instead, we run the task in a separate method and capture the result in a TaskCompletionSource. + // Then we can block synchronously on the TaskCompletionSource's Task to get the result. + var tcs = new TaskCompletionSource(); + + if (!InvokeRequired) + { + // We're already on the UI thread, so we spin up a new task to avoid blocking the UI thread. + _ = Invoke(async () => await Task.Run(Callback).ConfigureAwait(true)); + } + else + { + // We're already on a different thread, so we can just invoke the callback directly. + _ = Invoke(async () => await Callback().ConfigureAwait(true)); + } + + T? result = default; + + try + { + result = tcs.Task.Result; + } + catch (Exception ex) + { + // Should the task-wrapper throw, we want to preserve the original exception. + ExceptionDispatchInfo.Throw(ex); + } + + return result; + + async Task Callback() + { + try + { + var result = await asyncFunc().ConfigureAwait(true); + tcs.TrySetResult(result); + } + catch (Exception ex) + { + tcs.TrySetException(ex); + } + } + } + + /// + /// Invokes the specified synchronous function asynchronously on the thread that owns the control's handle. + /// + /// The return type of the synchronous function. + /// The synchronous function to execute. + /// The cancellation token. + /// A task representing the operation and containing the function's result. + public async Task InvokeSyncAsync(Func syncFunction, CancellationToken cancellationToken) + { + var tcs = new TaskCompletionSource(); + + if (!IsHandleCreated) + { + tcs.TrySetException(new InvalidOperationException("Control handle not created.")); + + return await tcs.Task.ConfigureAwait(true); + } + + var result = await Task.Run( + () => Invoke(() => syncFunction()), + cancellationToken).ConfigureAwait(true); + + tcs.TrySetResult(result); + + return await tcs.Task.ConfigureAwait(true); + } + + /// + /// Invokes the specified asynchronous function on the thread that owns the control's handle. + /// + /// The asynchronous function to execute. + /// The cancellation token. + /// A task representing the operation. + public async Task InvokeAsync(Func function, CancellationToken cancellationToken) + { + var tcs = new TaskCompletionSource(); + + if (!IsHandleCreated) + { + tcs.TrySetException(new InvalidOperationException("Control handle not created.")); + + await tcs.Task.ConfigureAwait(true); + } + + await Task.Run( + () => Invoke(async () => await function().ConfigureAwait(true)), + cancellationToken).ConfigureAwait(true); + + tcs.TrySetResult(); + + await tcs.Task.ConfigureAwait(true); + } + + /// + /// Executes the specified asynchronous function on the thread that owns the control's handle. + /// + /// The type of the input argument to be converted into the args array. + /// + /// The asynchronous function to execute, + /// which takes an input of type T and returns a . + /// + /// The cancellation token. + /// A task representing the operation and containing the function's result of type U. + /// Thrown if the control's handle is not yet created. + public async Task InvokeAsync(Func> asyncFunc, CancellationToken cancellationToken) + { + var tcs = new TaskCompletionSource(); + + if (!IsHandleCreated) + { + tcs.TrySetException(new InvalidOperationException("Control handle not created.")); + return await tcs.Task.ConfigureAwait(true); + } + + var result = await Task.Run( + () => Invoke(async () => await asyncFunc().ConfigureAwait(true)), + cancellationToken).ConfigureAwait(true); + + tcs.TrySetResult(result); + + return await tcs.Task.ConfigureAwait(true); + } + + /// + /// Executes the specified asynchronous function on the thread that owns the control's handle. + /// + /// The type of the input argument to be converted into the args array. + /// The return type of the asynchronous function. + /// + /// The asynchronous function to execute, which takes an input of type T + /// and returns a . + /// + /// The input argument to be converted into the args array. + /// The cancellation token. + /// A task representing the operation and containing the function's result of type U. + /// Thrown if the control's handle is not yet created. + public async Task InvokeAsync(Func> asyncFunc, T arg, CancellationToken cancellationToken) + { + var tcs = new TaskCompletionSource(); + + if (!IsHandleCreated) + { + tcs.TrySetException(new InvalidOperationException("Control handle not created.")); + return await tcs.Task.ConfigureAwait(true); + } + + await Task.Run( + () => Invoke(async () => await Callback().ConfigureAwait(true)), + cancellationToken).ConfigureAwait(true); + + return await tcs.Task.ConfigureAwait(true); + + async Task Callback() + { + try + { + var result = await asyncFunc(arg).ConfigureAwait(false); + tcs.TrySetResult(result); + } + catch (Exception ex) + { + tcs.SetException(ex); + } + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonBase.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonBase.cs index 6ceb9b5a715..dbf12c3fb3a 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonBase.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonBase.cs @@ -1256,7 +1256,7 @@ public bool UseCompatibleTextRendering [SRDescription(nameof(SR.ButtonUseVisualStyleBackColorDescr))] public bool UseVisualStyleBackColor { - get => (_isEnableVisualStyleBackgroundSet || (RawBackColor.IsEmpty && (BackColor == SystemColors.Control))) + get => (_isEnableVisualStyleBackgroundSet || (RawBackColor.IsEmpty && (BackColor == Application.SystemColors.Control))) && _enableVisualStyleBackground; set { diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonBaseAdapter.ColorOptions.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonBaseAdapter.ColorOptions.cs index 56a0721ea06..1816d6fc80d 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonBaseAdapter.ColorOptions.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonBaseAdapter.ColorOptions.cs @@ -37,11 +37,11 @@ internal ColorData Calculate() ButtonFace = _backColor }; - if (_backColor == SystemColors.Control) + if (_backColor == Application.SystemColors.Control) { - colors.ButtonShadow = SystemColors.ControlDark; - colors.ButtonShadowDark = SystemColors.ControlDarkDark; - colors.Highlight = SystemColors.ControlLightLight; + colors.ButtonShadow = Application.SystemColors.ControlDark; + colors.ButtonShadowDark = Application.SystemColors.ControlDarkDark; + colors.Highlight = Application.SystemColors.ControlLightLight; } else { @@ -59,7 +59,7 @@ internal ColorData Calculate() } } - colors.WindowDisabled = HighContrast ? SystemColors.GrayText : colors.ButtonShadow; + colors.WindowDisabled = HighContrast ? Application.SystemColors.GrayText : colors.ButtonShadow; const float lowlight = .1f; float adjust = 1 - lowlight; @@ -85,7 +85,7 @@ internal ColorData Calculate() Adjust255(adjust, colors.Highlight.G), Adjust255(adjust, colors.Highlight.B)); - if (HighContrast && _backColor != SystemColors.Control) + if (HighContrast && _backColor != Application.SystemColors.Control) { colors.Highlight = colors.LowHighlight; } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonBaseAdapter.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonBaseAdapter.cs index 750be56adf3..cbcd6eca1db 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonBaseAdapter.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonBaseAdapter.cs @@ -102,7 +102,7 @@ internal static void DrawDitheredFill(Graphics g, Color color1, Color color2, Re protected void Draw3DBorder(IDeviceContext deviceContext, Rectangle bounds, ColorData colors, bool raised) { - if (Control.BackColor != SystemColors.Control && SystemInformation.HighContrast) + if (Control.BackColor != Application.SystemColors.Control && SystemInformation.HighContrast) { if (raised) { @@ -128,7 +128,7 @@ protected void Draw3DBorder(IDeviceContext deviceContext, Rectangle bounds, Colo private void Draw3DBorderHighContrastRaised(IDeviceContext deviceContext, ref Rectangle bounds, ColorData colors) { - bool stockColor = colors.ButtonFace.ToKnownColor() == SystemColors.Control.ToKnownColor(); + bool stockColor = colors.ButtonFace.ToKnownColor() == Application.SystemColors.Control.ToKnownColor(); bool disabledHighContrast = (!Control.Enabled) && SystemInformation.HighContrast; using DeviceContextHdcScope hdc = deviceContext.ToHdcScope(); @@ -143,7 +143,7 @@ private void Draw3DBorderHighContrastRaised(IDeviceContext deviceContext, ref Re using CreatePenScope penTopLeft = new( disabledHighContrast ? colors.WindowDisabled - : stockColor ? SystemColors.ControlLightLight : colors.Highlight); + : stockColor ? Application.SystemColors.ControlLightLight : colors.Highlight); hdc.DrawLine(penTopLeft, p1, p2); // Top (right-left) hdc.DrawLine(penTopLeft, p2, p3); // Left (up-down) @@ -152,7 +152,7 @@ private void Draw3DBorderHighContrastRaised(IDeviceContext deviceContext, ref Re using CreatePenScope penBottomRight = new( disabledHighContrast ? colors.WindowDisabled - : stockColor ? SystemColors.ControlDarkDark : colors.ButtonShadowDark); + : stockColor ? Application.SystemColors.ControlDarkDark : colors.ButtonShadowDark); p1.Offset(0, -1); // Need to paint last pixel too. hdc.DrawLine(penBottomRight, p3, p4); // Bottom (left-right) @@ -161,7 +161,7 @@ private void Draw3DBorderHighContrastRaised(IDeviceContext deviceContext, ref Re // Draw inset using the background color to make the top and left lines thinner using CreatePenScope insetPen = new( stockColor - ? SystemInformation.HighContrast ? SystemColors.ControlLight : SystemColors.Control + ? SystemInformation.HighContrast ? Application.SystemColors.ControlLight : Application.SystemColors.Control : SystemInformation.HighContrast ? colors.Highlight : colors.ButtonFace); p1.Offset(-1, 2); @@ -177,7 +177,7 @@ private void Draw3DBorderHighContrastRaised(IDeviceContext deviceContext, ref Re using CreatePenScope bottomRightInsetPen = new( disabledHighContrast ? colors.WindowDisabled - : stockColor ? SystemColors.ControlDark : colors.ButtonShadow); + : stockColor ? Application.SystemColors.ControlDark : colors.ButtonShadow); p1.Offset(0, -1); // Need to paint last pixel too. hdc.DrawLine(bottomRightInsetPen, p3, p4); // Bottom (left-right) @@ -220,8 +220,8 @@ private static void Draw3DBorderNormal(IDeviceContext deviceContext, ref Rectang // Bottom + right inset using CreatePenScope insetPen = new( - colors.ButtonFace.ToKnownColor() == SystemColors.Control.ToKnownColor() - ? SystemColors.ControlLight + colors.ButtonFace.ToKnownColor() == Application.SystemColors.Control.ToKnownColor() + ? Application.SystemColors.ControlLight : colors.ButtonFace); p1.Offset(0, -1); // Need to paint last pixel too. @@ -231,7 +231,7 @@ private static void Draw3DBorderNormal(IDeviceContext deviceContext, ref Rectang private void Draw3DBorderRaised(IDeviceContext deviceContext, ref Rectangle bounds, ColorData colors) { - bool stockColor = colors.ButtonFace.ToKnownColor() == SystemColors.Control.ToKnownColor(); + bool stockColor = colors.ButtonFace.ToKnownColor() == Application.SystemColors.Control.ToKnownColor(); bool disabledHighContrast = (!Control.Enabled) && SystemInformation.HighContrast; using DeviceContextHdcScope hdc = deviceContext.ToHdcScope(); @@ -246,7 +246,7 @@ private void Draw3DBorderRaised(IDeviceContext deviceContext, ref Rectangle boun using CreatePenScope topLeftPen = new( disabledHighContrast ? colors.WindowDisabled - : stockColor ? SystemColors.ControlLightLight : colors.Highlight); + : stockColor ? Application.SystemColors.ControlLightLight : colors.Highlight); hdc.DrawLine(topLeftPen, p1, p2); // Top (right-left) hdc.DrawLine(topLeftPen, p2, p3); // Left (up-down) @@ -255,7 +255,7 @@ private void Draw3DBorderRaised(IDeviceContext deviceContext, ref Rectangle boun using CreatePenScope bottomRightPen = new( disabledHighContrast ? colors.WindowDisabled - : stockColor ? SystemColors.ControlDarkDark : colors.ButtonShadowDark); + : stockColor ? Application.SystemColors.ControlDarkDark : colors.ButtonShadowDark); p1.Offset(0, -1); // Need to paint last pixel too. hdc.DrawLine(bottomRightPen, p3, p4); // Bottom (left-right) @@ -270,7 +270,7 @@ private void Draw3DBorderRaised(IDeviceContext deviceContext, ref Rectangle boun using CreatePenScope topLeftInsetPen = new( !stockColor ? colors.ButtonFace - : SystemInformation.HighContrast ? SystemColors.ControlLight : SystemColors.Control); + : SystemInformation.HighContrast ? Application.SystemColors.ControlLight : Application.SystemColors.Control); // Top + left inset hdc.DrawLine(topLeftInsetPen, p1, p2); // Top (right-left) @@ -281,7 +281,7 @@ private void Draw3DBorderRaised(IDeviceContext deviceContext, ref Rectangle boun using CreatePenScope bottomRightInsetPen = new( disabledHighContrast ? colors.WindowDisabled - : stockColor ? SystemColors.ControlDark : colors.ButtonShadow); + : stockColor ? Application.SystemColors.ControlDark : colors.ButtonShadow); p1.Offset(0, -1); // Need to paint last pixel too. hdc.DrawLine(bottomRightInsetPen, p3, p4); // Bottom (left-right) diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonFlatAdapter.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonFlatAdapter.cs index 994bfa71cb6..28b0236c7fb 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonFlatAdapter.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonFlatAdapter.cs @@ -64,7 +64,7 @@ internal override void PaintUp(PaintEventArgs e, CheckState state) } } - PaintBackground(e, r, IsHighContrastHighlighted() ? SystemColors.Highlight : backColor); + PaintBackground(e, r, IsHighContrastHighlighted() ? Application.SystemColors.Highlight : backColor); if (Control.IsDefault) { @@ -72,7 +72,7 @@ internal override void PaintUp(PaintEventArgs e, CheckState state) } PaintImage(e, layout); - PaintField(e, layout, colors, IsHighContrastHighlighted() ? SystemColors.HighlightText : colors.WindowText, drawFocus: false); + PaintField(e, layout, colors, IsHighContrastHighlighted() ? Application.SystemColors.HighlightText : colors.WindowText, drawFocus: false); if (Control.Focused && Control.ShowFocusCues) { @@ -241,7 +241,7 @@ internal override void PaintOver(PaintEventArgs e, CheckState state) : colors.LowButtonFace; } - PaintBackground(e, r, IsHighContrastHighlighted() ? SystemColors.Highlight : backColor); + PaintBackground(e, r, IsHighContrastHighlighted() ? Application.SystemColors.Highlight : backColor); if (Control.IsDefault) { @@ -253,7 +253,7 @@ internal override void PaintOver(PaintEventArgs e, CheckState state) e, layout, colors, - IsHighContrastHighlighted() ? SystemColors.HighlightText : colors.WindowText, + IsHighContrastHighlighted() ? Application.SystemColors.HighlightText : colors.WindowText, drawFocus: false); if (Control.Focused && Control.ShowFocusCues) diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonPopupAdapter.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonPopupAdapter.cs index 31fe458ea77..accef664d43 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonPopupAdapter.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonPopupAdapter.cs @@ -24,7 +24,7 @@ internal override void PaintUp(PaintEventArgs e, CheckState state) } else { - Control.PaintBackground(e, r, IsHighContrastHighlighted() ? SystemColors.Highlight : Control.BackColor, r.Location); + Control.PaintBackground(e, r, IsHighContrastHighlighted() ? Application.SystemColors.Highlight : Control.BackColor, r.Location); } if (Control.IsDefault) @@ -37,7 +37,7 @@ internal override void PaintUp(PaintEventArgs e, CheckState state) e, layout, colors, - state != CheckState.Indeterminate && IsHighContrastHighlighted() ? SystemColors.HighlightText : colors.WindowText, + state != CheckState.Indeterminate && IsHighContrastHighlighted() ? Application.SystemColors.HighlightText : colors.WindowText, drawFocus: true); Color borderColor = colors.Options.HighContrast @@ -70,7 +70,7 @@ internal override void PaintOver(PaintEventArgs e, CheckState state) } else { - Control.PaintBackground(e, r, IsHighContrastHighlighted() ? SystemColors.Highlight : Control.BackColor, r.Location); + Control.PaintBackground(e, r, IsHighContrastHighlighted() ? Application.SystemColors.Highlight : Control.BackColor, r.Location); } if (Control.IsDefault) @@ -79,7 +79,7 @@ internal override void PaintOver(PaintEventArgs e, CheckState state) } PaintImage(e, layout); - PaintField(e, layout, colors, IsHighContrastHighlighted() ? SystemColors.HighlightText : colors.WindowText, drawFocus: true); + PaintField(e, layout, colors, IsHighContrastHighlighted() ? Application.SystemColors.HighlightText : colors.WindowText, drawFocus: true); DrawDefaultBorder(e, r, colors.Options.HighContrast ? colors.WindowText : colors.ButtonShadow, Control.IsDefault); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonStandardAdapter.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonStandardAdapter.cs index 7cf7e8cac5c..d138680f45d 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonStandardAdapter.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/ButtonStandardAdapter.cs @@ -70,7 +70,7 @@ private void PaintThemedButtonBackground(PaintEventArgs e, Rectangle bounds, boo if (!Control.UseVisualStyleBackColor) { bool isHighContrastHighlighted = up && IsHighContrastHighlighted(); - Color color = isHighContrastHighlighted ? SystemColors.Highlight : Control.BackColor; + Color color = isHighContrastHighlighted ? Application.SystemColors.Highlight : Control.BackColor; if (color.HasTransparency()) { @@ -164,7 +164,7 @@ private void PaintWorker(PaintEventArgs e, bool up, CheckState state) if (up & IsHighContrastHighlighted()) { - Color highlightTextColor = SystemColors.HighlightText; + Color highlightTextColor = Application.SystemColors.HighlightText; PaintField(e, layout, colors, highlightTextColor, drawFocus: false); if (Control.Focused && Control.ShowFocusCues) @@ -175,7 +175,7 @@ private void PaintWorker(PaintEventArgs e, bool up, CheckState state) } else if (up & IsHighContrastHighlighted()) { - PaintField(e, layout, colors, SystemColors.HighlightText, drawFocus: true); + PaintField(e, layout, colors, Application.SystemColors.HighlightText, drawFocus: true); } else { diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/CheckBoxBaseAdapter.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/CheckBoxBaseAdapter.cs index ae30fc150b6..8992ef80ce3 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/CheckBoxBaseAdapter.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/CheckBoxBaseAdapter.cs @@ -93,15 +93,15 @@ internal static void DrawCheckBackground( if (!controlEnabled && disabledColors) { - color = SystemColors.Control; + color = Application.SystemColors.Control; } - else if (controlCheckState == CheckState.Indeterminate && checkBackground == SystemColors.Window && disabledColors) + else if (controlCheckState == CheckState.Indeterminate && checkBackground == Application.SystemColors.Window && disabledColors) { - Color comboColor = SystemInformation.HighContrast ? SystemColors.ControlDark : SystemColors.Control; + Color comboColor = SystemInformation.HighContrast ? Application.SystemColors.ControlDark : Application.SystemColors.Control; color = Color.FromArgb( - (byte)((comboColor.R + SystemColors.Window.R) / 2), - (byte)((comboColor.G + SystemColors.Window.G) / 2), - (byte)((comboColor.B + SystemColors.Window.B) / 2)); + (byte)((comboColor.R + Application.SystemColors.Window.R) / 2), + (byte)((comboColor.G + Application.SystemColors.Window.G) / 2), + (byte)((comboColor.B + Application.SystemColors.Window.B) / 2)); } else { diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/RadioButtonBaseAdapter.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/RadioButtonBaseAdapter.cs index 7cb823a0d32..f14eecfb94f 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/RadioButtonBaseAdapter.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonInternal/RadioButtonBaseAdapter.cs @@ -34,7 +34,7 @@ protected void DrawCheckBackground3DLite( Color field = checkBackground; if (!Control.Enabled && disabledColors) { - field = SystemColors.Control; + field = Application.SystemColors.Control; } using var fieldBrush = field.GetCachedSolidBrushScope(); @@ -69,7 +69,7 @@ protected void DrawCheckBackgroundFlat(PaintEventArgs e, Rectangle bounds, Color } // Otherwise we are in HighContrast mode - field = SystemColors.Control; + field = Application.SystemColors.Control; } double scale = GetDpiScaleRatio(); @@ -139,7 +139,7 @@ protected void DrawCheckOnly(PaintEventArgs e, LayoutData layout, Color checkCol if (!Control.Enabled && disabledColors) { - checkColor = SystemColors.ControlDark; + checkColor = Application.SystemColors.ControlDark; } double scale = GetDpiScaleRatio(); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonRenderer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonRenderer.cs index c53f3191ed6..5282321bc9f 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonRenderer.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonRenderer.cs @@ -156,7 +156,7 @@ public static void DrawButton(Graphics g, Rectangle bounds, string? buttonText, { ControlPaint.DrawButton(g, bounds, ConvertToButtonState(state)); contentBounds = Rectangle.Inflate(bounds, -3, -3); - textColor = SystemColors.ControlText; + textColor = Application.SystemColors.ControlText; } TextRenderer.DrawText(g, buttonText, font, contentBounds, textColor, flags); @@ -267,7 +267,7 @@ internal static void DrawButton( } contentBounds = Rectangle.Inflate(bounds, -3, -3); - textColor = SystemColors.ControlText; + textColor = Application.SystemColors.ControlText; } TextRenderer.DrawText(deviceContext, buttonText, font, contentBounds, textColor, flags); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/CheckBoxRenderer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/CheckBoxRenderer.cs index d10dd6b81ab..081be6d6f5b 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/CheckBoxRenderer.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/CheckBoxRenderer.cs @@ -141,7 +141,7 @@ internal static void DrawCheckBox( ControlPaint.DrawCheckBox(g, glyphBounds, ConvertToButtonState(state)); } - textColor = SystemColors.ControlText; + textColor = Application.SystemColors.ControlText; } TextRenderer.DrawText(g, checkBoxText, font, textBounds, textColor, flags); @@ -213,7 +213,7 @@ public static void DrawCheckBox( ControlPaint.DrawCheckBox(g, glyphBounds, ConvertToButtonState(state)); } - textColor = SystemColors.ControlText; + textColor = Application.SystemColors.ControlText; } TextRenderer.DrawText(g, checkBoxText, font, textBounds, textColor, flags); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/RadioButtonRenderer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/RadioButtonRenderer.cs index 3668018ed62..4089bb3d9f2 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/RadioButtonRenderer.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/RadioButtonRenderer.cs @@ -141,7 +141,7 @@ internal static void DrawRadioButton( else { ControlPaint.DrawRadioButton(g, glyphBounds, ConvertToButtonState(state)); - textColor = SystemColors.ControlText; + textColor = Application.SystemColors.ControlText; } TextRenderer.DrawText(g, radioButtonText, font, textBounds, textColor, flags); @@ -234,7 +234,7 @@ internal static void DrawRadioButton( { g.DrawImage(image, imageBounds); ControlPaint.DrawRadioButton(g, glyphBounds, ConvertToButtonState(state)); - textColor = SystemColors.ControlText; + textColor = Application.SystemColors.ControlText; } TextRenderer.DrawText(g, radioButtonText, font, textBounds, textColor, flags); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ComboBox/ComboBox.FlatComboAdapter.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ComboBox/ComboBox.FlatComboAdapter.cs index 801cbd52d78..7e54c570664 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ComboBox/ComboBox.FlatComboAdapter.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ComboBox/ComboBox.FlatComboAdapter.cs @@ -168,19 +168,19 @@ protected virtual void DrawFlatComboDropDown(ComboBox comboBox, Graphics g, Rect } protected virtual Color GetOuterBorderColor(ComboBox comboBox) - => comboBox.Enabled ? SystemColors.Window : SystemColors.ControlDark; + => comboBox.Enabled ? Application.SystemColors.Window : Application.SystemColors.ControlDark; protected virtual Color GetPopupOuterBorderColor(ComboBox comboBox, bool focused) { if (!comboBox.Enabled) { - return SystemColors.ControlDark; + return Application.SystemColors.ControlDark; } - return focused ? SystemColors.ControlDark : SystemColors.Window; + return focused ? Application.SystemColors.ControlDark : Application.SystemColors.Window; } protected virtual Color GetInnerBorderColor(ComboBox comboBox) - => comboBox.Enabled ? comboBox.BackColor : SystemColors.Control; + => comboBox.Enabled ? comboBox.BackColor : Application.SystemColors.Control; } } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ComboBox/ComboBox.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ComboBox/ComboBox.cs index bcc8f460e10..65a61425bbc 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ComboBox/ComboBox.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ComboBox/ComboBox.cs @@ -263,7 +263,7 @@ public override Color BackColor } else { - return SystemColors.Window; + return Application.SystemColors.Window; } } set => base.BackColor = value; @@ -585,7 +585,7 @@ public override Color ForeColor } else { - return SystemColors.WindowText; + return Application.SystemColors.WindowText; } } set => base.ForeColor = value; @@ -2377,7 +2377,7 @@ protected override void CreateHandle() /// Inheriting classes should not forget to call /// base.OnHandleCreated() /// - protected override void OnHandleCreated(EventArgs e) + protected unsafe override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); @@ -2386,10 +2386,9 @@ protected override void OnHandleCreated(EventArgs e) PInvoke.SendMessage(this, PInvoke.CB_LIMITTEXT, (WPARAM)MaxLength); } - // Get the handles and wndprocs of the ComboBox's child windows - // - Debug.Assert(_childEdit is null, "Child edit window already attached"); - Debug.Assert(_childListBox is null, "Child listbox window already attached"); + // Get the handles and WndProcs of the ComboBox's child windows + Debug.Assert(_childEdit is null, "Child Edit window is already attached."); + Debug.Assert(_childListBox is null, "Child ListBox window is already attached."); bool ok = _childEdit is null && _childListBox is null; @@ -2398,7 +2397,7 @@ protected override void OnHandleCreated(EventArgs e) HWND hwnd = PInvoke.GetWindow(this, GET_WINDOW_CMD.GW_CHILD); if (!hwnd.IsNull) { - // If it's a simple dropdown list, the first HWND is the list box. + // If it's a simple dropdown list, the first HWND is the ListBox. if (DropDownStyle == ComboBoxStyle.Simple) { _childListBox = new ComboBoxChildNativeWindow(this, ChildWindowType.ListBox); @@ -2411,7 +2410,7 @@ protected override void OnHandleCreated(EventArgs e) _childEdit = new ComboBoxChildNativeWindow(this, ChildWindowType.Edit); _childEdit.AssignHandle(hwnd); - // Set the initial margin for combobox to be zero (this is also done whenever the font is changed). + // Set the initial margin for ComboBox to be zero (this is also done whenever the font is changed). PInvoke.SendMessage(_childEdit, PInvoke.EM_SETMARGINS, (WPARAM)(PInvoke.EC_LEFTMARGIN | PInvoke.EC_RIGHTMARGIN)); } } @@ -2429,7 +2428,7 @@ protected override void OnHandleCreated(EventArgs e) UpdateItemHeight(); } - // Resize a simple style combobox on handle creation + // Resize a simple style ComboBox on handle creation // to respect the requested height. // if (DropDownStyle == ComboBoxStyle.Simple) @@ -2438,7 +2437,7 @@ protected override void OnHandleCreated(EventArgs e) } // If HandleCreated set the AutoComplete... - // this function checks if the correct properties are set to enable AutoComplete feature on combobox. + // This function checks if the correct properties are set to enable AutoComplete feature on ComboBox. try { _fromHandleCreate = true; @@ -2449,6 +2448,18 @@ protected override void OnHandleCreated(EventArgs e) _fromHandleCreate = false; } + if (IsDarkModeEnabled) + { + // Style the ComboBox Open-Button: + PInvoke.SetWindowTheme(HWND, "DarkMode_CFD", null); + COMBOBOXINFO cInfo = default; + cInfo.cbSize = (uint)sizeof(COMBOBOXINFO); + + // Style the ComboBox drop-down (including its ScrollBar(s)): + var result = PInvoke.GetComboBoxInfo(HWND, ref cInfo); + PInvoke.SetWindowTheme(cInfo.hwndList, "DarkMode_Explorer", null); + } + if (_itemsCollection is not null) { foreach (object item in _itemsCollection) @@ -2465,7 +2476,7 @@ protected override void OnHandleCreated(EventArgs e) } } - // NOTE: Setting SelectedIndex must be the last thing we do. + // NOTE: Setting SelectedIndex must be the last thing we do! } /// @@ -2722,7 +2733,7 @@ protected override void OnSelectedIndexChanged(EventArgs e) // don't change the position if SelectedIndex is -1 because this indicates a selection not from the list. if (DataManager is not null && DataManager.Position != SelectedIndex) { - // read this as "if everett or (whidbey and selindex is valid)" + // read this as "if Everett or (Whidbey and selIndex is valid)" if (!FormattingEnabled || SelectedIndex != -1) { DataManager.Position = SelectedIndex; @@ -2756,7 +2767,7 @@ protected virtual void OnDropDownStyleChanged(EventArgs e) /// /// This method is called by the parent control when any property - /// changes on the parent. This can be overriden by inheriting + /// changes on the parent. This can be overridden by inheriting /// classes, however they must call base.OnParentPropertyChanged. /// protected override void OnParentBackColorChanged(EventArgs e) @@ -3572,7 +3583,7 @@ private void WmEraseBkgnd(ref Message m) { PInvokeCore.GetClientRect(this, out RECT rect); HDC hdc = (HDC)m.WParamInternal; - using var hbrush = new CreateBrushScope(ParentInternal?.BackColor ?? SystemColors.Control); + using var hbrush = new CreateBrushScope(ParentInternal?.BackColor ?? Application.SystemColors.Control); hdc.FillRectangle(rect, hbrush); m.ResultInternal = (LRESULT)1; return; @@ -3851,7 +3862,7 @@ protected override unsafe void WndProc(ref Message m) case PInvoke.WM_PAINT: if (!GetStyle(ControlStyles.UserPaint) && (FlatStyle == FlatStyle.Flat || FlatStyle == FlatStyle.Popup) - && !(SystemInformation.HighContrast && BackColor == SystemColors.Window)) + && !(SystemInformation.HighContrast && BackColor == Application.SystemColors.Window)) { using RegionScope dropDownRegion = new(FlatComboBoxAdapter._dropDownRect); using RegionScope windowRegion = new(Bounds); 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..760e4fea4fa 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 @@ -32,7 +32,7 @@ private static void DrawBackground(Graphics g, Rectangle bounds, ComboBoxState s if (state != ComboBoxState.Disabled) { Color windowColor = t_visualStyleRenderer.GetColor(ColorProperty.FillColor); - if (windowColor != SystemColors.Window) + if (windowColor != Application.SystemColors.Window) { Rectangle fillRect = t_visualStyleRenderer.GetBackgroundContentRectangle(g, bounds); fillRect.Inflate(-2, -2); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridView.Methods.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridView.Methods.cs index 071be810fa1..153dbbf2b2f 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridView.Methods.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridView.Methods.cs @@ -5826,7 +5826,7 @@ private void DrawColHeaderShadow(Graphics g, int mouseX) if (ApplyVisualStylesToHeaderCells) { - using var brush = SystemColors.HotTrack.GetCachedSolidBrushScope(); + using var brush = Application.SystemColors.HotTrack.GetCachedSolidBrushScope(); g.FillRectangle(brush, rectInsertionBar); } else @@ -17103,7 +17103,7 @@ protected override void OnPaint(PaintEventArgs e) { if (SystemInformation.HighContrast) { - ControlPaint.DrawHighContrastFocusRectangle(g, GetGridFocusRectangle(), SystemColors.ActiveCaptionText); + ControlPaint.DrawHighContrastFocusRectangle(g, GetGridFocusRectangle(), Application.SystemColors.ActiveCaptionText); } else { @@ -19744,7 +19744,7 @@ private void PaintBorder(Graphics g, Rectangle clipRect, Rectangle bounds) } else if (BorderStyle == BorderStyle.FixedSingle) { - using var pen = SystemColors.ControlText.GetCachedPenScope(); + using var pen = Application.SystemColors.ControlText.GetCachedPenScope(); g.DrawRectangle(pen, new Rectangle(0, 0, bounds.Width - 1, bounds.Height - 1)); } else diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridView.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridView.cs index 1bd46beaa36..c0d43686f06 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridView.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridView.cs @@ -353,8 +353,8 @@ private const DataGridViewAutoSizeRowCriteriaInternal InvalidDataGridViewAutoSiz private Timer? _horizScrollTimer; private readonly Dictionary _converters; - private static readonly Color s_defaultBackColor = SystemColors.Window; - private static readonly Color s_defaultBackgroundColor = SystemColors.ControlDark; + private static readonly Color s_defaultBackColor = Application.SystemColors.Window; + private static readonly Color s_defaultBackgroundColor = Application.SystemColors.ControlDark; private Color _backgroundColor = s_defaultBackgroundColor; private RECT[]? _cachedScrollableRegion; @@ -2073,7 +2073,7 @@ public event EventHandler? DefaultCellStyleChanged private static SolidBrush DefaultForeBrush => (SolidBrush)SystemBrushes.WindowText; - private static Color DefaultGridColor => SystemColors.WindowFrame; + private static Color DefaultGridColor => Application.SystemColors.WindowFrame; private static SolidBrush DefaultHeadersBackBrush => (SolidBrush)SystemBrushes.Control; 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 cd3b4bc9baf..ce7a194ae72 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 @@ -783,7 +783,7 @@ private Rectangle PaintPrivate( ControlPaint.DrawBorder( g, valBounds, - SystemColors.Control, + Application.SystemColors.Control, (ButtonState == ButtonState.Normal) ? ButtonBorderStyle.Outset : ButtonBorderStyle.Inset); } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewCell.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewCell.cs index 3a1dd9b1e1d..cd8701d2759 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewCell.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewCell.cs @@ -1467,8 +1467,8 @@ private static Bitmap GetBitmap(string bitmapName) => { Debug.Assert(DataGridView is not null); - int darkDistance = ColorDistance(baseline, SystemColors.ControlDark); - int lightDistance = ColorDistance(baseline, SystemColors.ControlLightLight); + int darkDistance = ColorDistance(baseline, Application.SystemColors.ControlDark); + int lightDistance = ColorDistance(baseline, Application.SystemColors.ControlLightLight); Color darkColor; Color lightColor; @@ -1477,21 +1477,21 @@ private static Bitmap GetBitmap(string bitmapName) => { darkColor = darkDistance < HighContrastThreshold ? ControlPaint.DarkDark(baseline) - : SystemColors.ControlDark; + : Application.SystemColors.ControlDark; lightColor = lightDistance < HighContrastThreshold ? ControlPaint.LightLight(baseline) - : SystemColors.ControlLightLight; + : Application.SystemColors.ControlLightLight; } else { darkColor = darkDistance < ContrastThreshold ? ControlPaint.Dark(baseline) - : SystemColors.WindowFrame; + : Application.SystemColors.WindowFrame; lightColor = lightDistance < ContrastThreshold ? ControlPaint.Light(baseline) - : SystemColors.ControlLightLight; + : Application.SystemColors.ControlLightLight; } return (darkColor, lightColor); @@ -3187,8 +3187,8 @@ protected virtual void PaintBorder( Color dividerWidthColor = advancedBorderStyle.Right switch { DataGridViewAdvancedCellBorderStyle.Single => DataGridView.GridPenColor, - DataGridViewAdvancedCellBorderStyle.Inset => SystemColors.ControlLightLight, - _ => SystemColors.ControlDark, + DataGridViewAdvancedCellBorderStyle.Inset => Application.SystemColors.ControlLightLight, + _ => Application.SystemColors.ControlDark, }; using var dividerWidthBrush = dividerWidthColor.GetCachedSolidBrushScope(); @@ -3222,8 +3222,8 @@ protected virtual void PaintBorder( Color dividerHeightColor = advancedBorderStyle.Bottom switch { DataGridViewAdvancedCellBorderStyle.Single => DataGridView.GridPenColor, - DataGridViewAdvancedCellBorderStyle.Inset => SystemColors.ControlLightLight, - _ => SystemColors.ControlDark, + DataGridViewAdvancedCellBorderStyle.Inset => Application.SystemColors.ControlLightLight, + _ => Application.SystemColors.ControlDark, }; using var dividerHeightColorBrush = dividerHeightColor.GetCachedSolidBrushScope(); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewLinkCell.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewLinkCell.cs index 62587b284fd..6d0932cb836 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewLinkCell.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewLinkCell.cs @@ -55,7 +55,7 @@ public Color ActiveLinkColor else { // return the default IE Color if cell is not not selected - return Selected ? SystemColors.HighlightText : LinkUtilities.IEActiveLinkColor; + return Selected ? Application.SystemColors.HighlightText : LinkUtilities.IEActiveLinkColor; } } set @@ -173,7 +173,7 @@ public Color LinkColor else { // return the default IE Color when cell is not selected - return Selected ? SystemColors.HighlightText : LinkUtilities.IELinkColor; + return Selected ? Application.SystemColors.HighlightText : LinkUtilities.IELinkColor; } } set @@ -352,12 +352,12 @@ public Color VisitedLinkColor } else if (SystemInformation.HighContrast) { - return Selected ? SystemColors.HighlightText : LinkUtilities.GetVisitedLinkColor(); + return Selected ? Application.SystemColors.HighlightText : LinkUtilities.GetVisitedLinkColor(); } else { // return the default IE Color if cell is not not selected - return Selected ? SystemColors.HighlightText : LinkUtilities.IEVisitedLinkColor; + return Selected ? Application.SystemColors.HighlightText : LinkUtilities.IEVisitedLinkColor; } } set @@ -406,9 +406,9 @@ private Color HighContrastLinkColor [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - // Selected cells have SystemColors.Highlight as a background. - // SystemColors.HighlightText is supposed to be in contrast with SystemColors.Highlight. - return Selected ? SystemColors.HighlightText : SystemColors.HotTrack; + // Selected cells have Application.SystemColors.Highlight as a background. + // Application.SystemColors.HighlightText is supposed to be in contrast with Application.SystemColors.Highlight. + return Selected ? Application.SystemColors.HighlightText : Application.SystemColors.HotTrack; } } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DateTimePicker/DateTimePicker.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DateTimePicker/DateTimePicker.cs index 61f1acb7e13..497e89c56e9 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DateTimePicker/DateTimePicker.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DateTimePicker/DateTimePicker.cs @@ -25,22 +25,22 @@ public partial class DateTimePicker : Control /// /// Specifies the default title back color. This field is read-only. /// - protected static readonly Color DefaultTitleBackColor = SystemColors.ActiveCaption; + protected static readonly Color DefaultTitleBackColor = Application.SystemColors.ActiveCaption; /// /// Specifies the default foreground color. This field is read-only. /// - protected static readonly Color DefaultTitleForeColor = SystemColors.ActiveCaptionText; + protected static readonly Color DefaultTitleForeColor = Application.SystemColors.ActiveCaptionText; /// /// Specifies the default month background color. This field is read-only. /// - protected static readonly Color DefaultMonthBackColor = SystemColors.Window; + protected static readonly Color DefaultMonthBackColor = Application.SystemColors.Window; /// /// Specifies the default trailing foreground color. This field is read-only. /// - protected static readonly Color DefaultTrailingForeColor = SystemColors.GrayText; + protected static readonly Color DefaultTrailingForeColor = Application.SystemColors.GrayText; private static readonly object s_formatChangedEvent = new(); @@ -80,7 +80,7 @@ public partial class DateTimePicker : Control private bool _validTime = true; // DateTime changeover: DateTime is a value class, not an object, so we need to keep track - // of whether or not its values have been initialised in a separate boolean. + // of whether or not its values have been initialized in a separate boolean. private bool _userHasSetValue; private DateTime _value = DateTime.Now; private DateTime _creationTime = DateTime.Now; @@ -127,7 +127,7 @@ public DateTimePicker() : base() [EditorBrowsable(EditorBrowsableState.Never)] public override Color BackColor { - get => ShouldSerializeBackColor() ? base.BackColor : SystemColors.Window; + get => ShouldSerializeBackColor() || IsDarkModeEnabled ? base.BackColor : Application.SystemColors.Window; set => base.BackColor = value; } @@ -488,7 +488,7 @@ public LeftRightAlignment DropDownAlign [EditorBrowsable(EditorBrowsableState.Never)] public override Color ForeColor { - get => ShouldSerializeForeColor() ? base.ForeColor : SystemColors.WindowText; + get => ShouldSerializeForeColor() || IsDarkModeEnabled ? base.ForeColor : Application.SystemColors.WindowText; set => base.ForeColor = value; } @@ -1083,7 +1083,7 @@ protected override void OnGotFocus(EventArgs e) { base.OnGotFocus(e); - // Raise automation event to annouce the control. + // Raise automation event to announce the control. if (IsAccessibilityObjectCreated) { _expandCollapseState = ExpandCollapseState.ExpandCollapseState_Collapsed; @@ -1133,7 +1133,7 @@ protected virtual void OnValueChanged(EventArgs eventargs) { _onValueChanged?.Invoke(this, eventargs); - // Raise automation event to annouce changed value. + // Raise automation event to announce changed value. if (IsAccessibilityObjectCreated) { // If date is changed so dtp value is changed too. diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/GroupBox/GroupBox.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/GroupBox/GroupBox.cs index e571f240124..b463bfffa3b 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/GroupBox/GroupBox.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/GroupBox/GroupBox.cs @@ -397,8 +397,8 @@ protected override void OnPaint(PaintEventArgs e) { // BACKCOMPAT requirement: // - // Why the Height/Width < 10 check? This is because uxtheme doesn't seem to handle those cases similar to - // what we do for the non-themed case, so if someone is using the groupbox as a separator, their app will + // Why the Height/Width < 10 check? This is because Ux-theme doesn't seem to handle those cases similar to + // what we do for the non-themed case, so if someone is using the GroupBox as a separator, their app will // look weird in .NET Framework 2.0. We render the old way in these cases. if (!Application.RenderWithVisualStyles || Width < 10 || Height < 10) @@ -424,15 +424,15 @@ protected override void OnPaint(PaintEventArgs e) // We only pass in the text color if it is explicitly set, else we let the renderer use the color // specified by the theme. This is a temporary workaround till we find a good solution for the // "default theme color" issue. - if (ShouldSerializeForeColor() || !Enabled) + if (ShouldSerializeForeColor() || IsDarkModeEnabled || !Enabled) { - Color textcolor = Enabled ? ForeColor : TextRenderer.DisabledTextColor(BackColor); + Color textColor = Enabled ? ForeColor : TextRenderer.DisabledTextColor(BackColor); GroupBoxRenderer.DrawGroupBox( e, new Rectangle(0, 0, Width, Height), Text, Font, - textcolor, + textColor, textFlags, gbState); } @@ -541,7 +541,7 @@ private void DrawGroupBox(PaintEventArgs e) if (SystemInformation.HighContrast) { - Color boxColor = Enabled ? ForeColor : SystemColors.GrayText; + Color boxColor = Enabled ? ForeColor : Application.SystemColors.GrayText; ReadOnlySpan lines = [ diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/GroupBox/GroupBoxRenderer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/GroupBox/GroupBoxRenderer.cs index 6a99fb44afc..ce86e01a4e6 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/GroupBox/GroupBoxRenderer.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/GroupBox/GroupBoxRenderer.cs @@ -245,7 +245,7 @@ private static void DrawThemedGroupBoxWithText( /// private static void DrawUnthemedGroupBoxNoText(Graphics g, Rectangle bounds) { - Color backColor = SystemColors.Control; + Color backColor = Application.SystemColors.Control; using var light = ControlPaint.Light(backColor, 1.0f).GetCachedPenScope(); using var dark = ControlPaint.Dark(backColor, 0f).GetCachedPenScope(); @@ -350,7 +350,7 @@ private static Color DefaultTextColor(GroupBoxState state) } else { - return SystemColors.ControlText; + return Application.SystemColors.ControlText; } } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Labels/LinkLabel.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Labels/LinkLabel.cs index f87d68bc506..42cffda5994 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Labels/LinkLabel.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Labels/LinkLabel.cs @@ -235,7 +235,7 @@ public LinkBehavior LinkBehavior public Color LinkColor { get => _linkColor.IsEmpty - ? SystemInformation.HighContrast ? SystemColors.HotTrack : IELinkColor + ? SystemInformation.HighContrast ? Application.SystemColors.HotTrack : IELinkColor : _linkColor; set { diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Labels/LinkUtilities.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Labels/LinkUtilities.cs index ef1d349e2f0..04ddf00dd12 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Labels/LinkUtilities.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Labels/LinkUtilities.cs @@ -113,9 +113,9 @@ public static Color IEVisitedLinkColor /// Produces a color for visited links using SystemColors public static Color GetVisitedLinkColor() { - int r = (SystemColors.Window.R + SystemColors.WindowText.R + 1) / 2; - int g = SystemColors.WindowText.G; - int b = (SystemColors.Window.B + SystemColors.WindowText.B + 1) / 2; + int r = (SystemColors.Window.R + Application.SystemColors.WindowText.R + 1) / 2; + int g = Application.SystemColors.WindowText.G; + int b = (SystemColors.Window.B + Application.SystemColors.WindowText.B + 1) / 2; return Color.FromArgb(r, g, b); } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListBoxes/CheckedListBox.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListBoxes/CheckedListBox.cs index 4706faff713..fe4178759aa 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListBoxes/CheckedListBox.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListBoxes/CheckedListBox.cs @@ -582,7 +582,7 @@ protected override void OnDrawItem(DrawItemEventArgs e) Color foreColor = (SelectionMode != SelectionMode.None) ? e.ForeColor : ForeColor; if (!Enabled) { - foreColor = SystemColors.GrayText; + foreColor = Application.SystemColors.GrayText; } Font font = Font; @@ -595,13 +595,13 @@ protected override void OnDrawItem(DrawItemEventArgs e) { if (Enabled) { - backColor = SystemColors.Highlight; - foreColor = SystemColors.HighlightText; + backColor = Application.SystemColors.Highlight; + foreColor = Application.SystemColors.HighlightText; } else { - backColor = SystemColors.InactiveBorder; - foreColor = SystemColors.GrayText; + backColor = Application.SystemColors.InactiveBorder; + foreColor = Application.SystemColors.GrayText; } } @@ -728,7 +728,7 @@ protected override void OnDrawItem(DrawItemEventArgs e) Color foreColor = (SelectionMode != SelectionMode.None) ? e.ForeColor : ForeColor; if (!Enabled) { - foreColor = SystemColors.GrayText; + foreColor = Application.SystemColors.GrayText; } ControlPaint.DrawFocusRectangle(e.Graphics, emptyRectangle, foreColor, backColor); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListBoxes/ListBox.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListBoxes/ListBox.cs index 45c8743a214..9c0eae90f02 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListBoxes/ListBox.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListBoxes/ListBox.cs @@ -156,7 +156,7 @@ public override Color BackColor } else { - return SystemColors.Window; + return Application.SystemColors.Window; } } set => base.BackColor = value; @@ -449,7 +449,7 @@ public override Color ForeColor } else { - return SystemColors.WindowText; + return Application.SystemColors.WindowText; } } set => base.ForeColor = value; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListView.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListView.cs index 162d5f670b5..98e268dfce9 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListView.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListView.cs @@ -103,8 +103,8 @@ public partial class ListView : Control // Ownerdraw data caches... Only valid inside WM_PAINT. - private Color _odCacheForeColor = SystemColors.WindowText; - private Color _odCacheBackColor = SystemColors.Window; + private Color _odCacheForeColor = Application.SystemColors.WindowText; + private Color _odCacheBackColor = Application.SystemColors.Window; private Font _odCacheFont; private HFONT _odCacheFontHandle; private FontHandleWrapper? _odCacheFontHandleWrapper; @@ -353,7 +353,7 @@ public override Color BackColor } else { - return SystemColors.Window; + return Application.SystemColors.Window; } } set @@ -853,7 +853,7 @@ public override Color ForeColor } else { - return SystemColors.WindowText; + return Application.SystemColors.WindowText; } } set @@ -2882,7 +2882,7 @@ private unsafe void CustomDraw(ref Message m) } // Work-around for a comctl quirk where, - // if clrText is the same as SystemColors.HotTrack, + // if clrText is the same as Application.SystemColors.HotTrack, // the subitem's color is not changed to nmcd->clrText. // // Try to tweak the blue component of clrText first, then green, then red. @@ -2920,7 +2920,7 @@ private unsafe void CustomDraw(ref Message m) mask >>= 8; // Try the next color. // We try adjusting Blue, Green, Red in that order, // since 0x0000FF is the most likely value of - // SystemColors.HotTrack + // Application.SystemColors.HotTrack totalshift += 8; } } @@ -4613,8 +4613,18 @@ protected override void OnHandleCreated(EventArgs e) PInvoke.SendMessage(this, PInvoke.CCM_SETVERSION, (WPARAM)5); } + if (IsDarkModeEnabled) + { + _ = PInvoke.SetWindowTheme(HWND, "DarkMode_Explorer", null); + + // Get the ListView's ColumnHeader handle: + var columnHeaderHandle = (HWND)PInvoke.SendMessage(this, PInvoke.LVM_GETHEADER, (WPARAM)0, (LPARAM)0); + PInvoke.SetWindowTheme(columnHeaderHandle, "DarkMode_ItemsView", null); + } + UpdateExtendedStyles(); RealizeProperties(); + PInvoke.SendMessage(this, PInvoke.LVM_SETBKCOLOR, (WPARAM)0, (LPARAM)BackColor); PInvoke.SendMessage(this, PInvoke.LVM_SETTEXTCOLOR, (WPARAM)0, (LPARAM)ForeColor); @@ -4622,7 +4632,7 @@ protected override void OnHandleCreated(EventArgs e) // This not noticeable if the customer paints the items w/ the same background color as the list view itself. // However, if the customer paints the items w/ a color different from the list view's back color // then when the user changes selection the native list view will not invalidate the entire list view item area. - PInvoke.SendMessage(this, PInvoke.LVM_SETTEXTBKCOLOR, (WPARAM)0, (LPARAM)PInvoke.CLR_NONE); + // PInvoke.SendMessage(this, PInvoke.LVM_SETTEXTBKCOLOR, (WPARAM)0, (LPARAM)PInvoke.CLR_NONE); // LVS_NOSCROLL does not work well when the list view is in View.Details or in View.List modes. // we have to set this style after the list view was created and before we position the native list view items. @@ -5008,13 +5018,13 @@ protected void RealizeProperties() Color c; c = BackColor; - if (c != SystemColors.Window) + if (c != Application.SystemColors.Window || IsDarkModeEnabled) { PInvoke.SendMessage(this, PInvoke.LVM_SETBKCOLOR, (WPARAM)0, (LPARAM)c); } c = ForeColor; - if (c != SystemColors.WindowText) + if (c != Application.SystemColors.WindowText || IsDarkModeEnabled) { PInvoke.SendMessage(this, PInvoke.LVM_SETTEXTCOLOR, (WPARAM)0, (LPARAM)c); } @@ -5924,7 +5934,7 @@ private void WmNmClick() private void WmNmDblClick() { - // If we're checked, hittest to see if we're + // If we're checked, hit-test to see if we're // on the item if (!CheckBoxes || VirtualMode) @@ -6007,6 +6017,29 @@ private unsafe bool WmNotify(ref Message m) { NMHDR* nmhdr = (NMHDR*)(nint)m.LParamInternal; + // We need to set the text color when we are in dark mode, + // so that the themed headers are actually readable. + if (IsDarkModeEnabled && !OwnerDraw && nmhdr->code == PInvoke.NM_CUSTOMDRAW) + { + NMLVCUSTOMDRAW* nmlvcd = (NMLVCUSTOMDRAW*)(nint)m.LParamInternal; + + if (nmlvcd->nmcd.dwDrawStage == NMCUSTOMDRAW_DRAW_STAGE.CDDS_PREPAINT) + { + // Request item draw notifications. + m.ResultInternal = (LRESULT)(nint)PInvoke.CDRF_NOTIFYITEMDRAW; + return true; // And done. + } + + else if (nmlvcd->nmcd.dwDrawStage == NMCUSTOMDRAW_DRAW_STAGE.CDDS_ITEMPREPAINT) + { + PInvoke.SetTextColor(nmlvcd->nmcd.hdc, ForeColor); + + // ...and then just let the default handling play out. + m.ResultInternal = (LRESULT)(nint)PInvoke.CDRF_DODEFAULT; + return false; + } + } + if (nmhdr->code == PInvoke.NM_CUSTOMDRAW && PInvoke.UiaClientsAreListening()) { // Checking that mouse buttons are not pressed is necessary to avoid diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListViewItem.ListViewSubItem.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListViewItem.ListViewSubItem.cs index a6eaead932e..f49ca226613 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListViewItem.ListViewSubItem.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListViewItem.ListViewSubItem.cs @@ -77,7 +77,7 @@ public Color BackColor return style.backColor; } - return _owner?._listView?.BackColor ?? SystemColors.Window; + return _owner?._listView?.BackColor ?? Application.SystemColors.Window; } set { @@ -170,7 +170,7 @@ public Color ForeColor return style.foreColor; } - return _owner?._listView?.ForeColor ?? SystemColors.WindowText; + return _owner?._listView?.ForeColor ?? Application.SystemColors.WindowText; } set { diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListViewItem.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListViewItem.cs index e1131e1ec27..9a8f1942ff6 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListViewItem.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListViewItem.cs @@ -288,7 +288,7 @@ public Color BackColor return _listView.BackColor; } - return SystemColors.Window; + return Application.SystemColors.Window; } else { @@ -419,7 +419,7 @@ public Color ForeColor return _listView.ForeColor; } - return SystemColors.WindowText; + return Application.SystemColors.WindowText; } else { diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/MonthCalendar/MonthCalendar.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/MonthCalendar/MonthCalendar.cs index 57e02247556..742c20360d0 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/MonthCalendar/MonthCalendar.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/MonthCalendar/MonthCalendar.cs @@ -59,9 +59,9 @@ namespace System.Windows.Forms; [SRDescription(nameof(SR.DescriptionMonthCalendar))] public partial class MonthCalendar : Control { - private static readonly Color s_defaultTitleBackColor = SystemColors.ActiveCaption; - private static readonly Color s_defaultTitleForeColor = SystemColors.ActiveCaptionText; - private static readonly Color s_trailingForeColor = SystemColors.GrayText; + private static readonly Color s_defaultTitleBackColor = Application.SystemColors.ActiveCaption; + private static readonly Color s_defaultTitleForeColor = Application.SystemColors.ActiveCaptionText; + private static readonly Color s_trailingForeColor = Application.SystemColors.GrayText; private const int MonthsInYear = 12; /// @@ -73,7 +73,7 @@ public partial class MonthCalendar : Control /// /// This is the arbitrary number of pixels that the Win32 control /// inserts between calendars vertically, regardless of font. - /// From comctl32 MonthCalendar sources CALBORDER. + /// From ComCtl32 MonthCalendar sources CALBORDER. /// private const int InsertHeightSize = 6; @@ -193,12 +193,12 @@ public override Color BackColor { get { - if (ShouldSerializeBackColor()) + if (ShouldSerializeBackColor() || IsDarkModeEnabled) { return base.BackColor; } - return SystemColors.Window; + return Application.SystemColors.Window; } set => base.BackColor = value; } @@ -407,12 +407,12 @@ public override Color ForeColor { get { - if (ShouldSerializeForeColor()) + if (ShouldSerializeForeColor() || IsDarkModeEnabled) { return base.ForeColor; } - return SystemColors.WindowText; + return Application.SystemColors.WindowText; } set => base.ForeColor = value; } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ProgressBar/ProgressBar.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ProgressBar/ProgressBar.cs index 747186dc107..31d38405405 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ProgressBar/ProgressBar.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ProgressBar/ProgressBar.cs @@ -25,7 +25,7 @@ public partial class ProgressBar : Control private int _marqueeAnimationSpeed = 100; - private static readonly Color s_defaultForeColor = SystemColors.Highlight; + private static readonly Color s_defaultForeColor = Application.SystemColors.Highlight; private ProgressBarStyle _style = ProgressBarStyle.Blocks; @@ -60,6 +60,7 @@ protected override CreateParams CreateParams { // We want to turn on mirroring for Form explicitly. cp.ExStyle |= (int)WINDOW_EX_STYLE.WS_EX_LAYOUTRTL; + // Don't need these styles when mirroring is turned on. cp.ExStyle &= ~(int)(WINDOW_EX_STYLE.WS_EX_RTLREADING | WINDOW_EX_STYLE.WS_EX_RIGHT | WINDOW_EX_STYLE.WS_EX_LEFTSCROLLBAR); } @@ -68,6 +69,20 @@ protected override CreateParams CreateParams } } + protected override void OnCreateControl() + { + base.OnCreateControl(); + + // If DarkMode is enabled, we need to disable the Visual Styles + // so Windows allows setting Fore- and Background color. + // There are more ideal ways imaginable, but this does the trick for now. + if (IsDarkModeEnabled) + { + // Disables Visual Styles for the ProgressBar. + PInvoke.SetWindowTheme(HWND, " ", " "); + } + } + [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] public override bool AllowDrop diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGrid.SnappableControl.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGrid.SnappableControl.cs index 932e84aff75..c57f39fb008 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGrid.SnappableControl.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGrid.SnappableControl.cs @@ -32,7 +32,7 @@ protected override void OnControlAdded(ControlEventArgs ce) { } - public Color BorderColor { get; set; } = SystemColors.ControlDark; + public Color BorderColor { get; set; } = Application.SystemColors.ControlDark; protected override void OnPaint(PaintEventArgs e) { diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGrid.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGrid.cs index e80bee69620..cc103c7ff0c 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGrid.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGrid.cs @@ -70,12 +70,16 @@ public partial class PropertyGrid : ContainerControl, IComPropertyBrowser, IProp private object[]? _selectedObjects; private int _paintFrozen; - private Color _lineColor = SystemInformation.HighContrast ? SystemColors.ControlDarkDark : SystemColors.InactiveBorder; - private Color _categoryForegroundColor = SystemColors.ControlText; - private Color _categorySplitterColor = SystemColors.Control; - private Color _viewBorderColor = SystemColors.ControlDark; - private Color _selectedItemWithFocusForeColor = SystemColors.HighlightText; - private Color _selectedItemWithFocusBackColor = SystemColors.Highlight; + + private Color _lineColor = SystemInformation.HighContrast + ? Application.SystemColors.ControlDarkDark + : Application.SystemColors.InactiveBorder; + + private Color _categoryForegroundColor = Application.SystemColors.ControlText; + private Color _categorySplitterColor = Application.SystemColors.Control; + private Color _viewBorderColor = Application.SystemColors.ControlDark; + private Color _selectedItemWithFocusForeColor = Application.SystemColors.HighlightText; + private Color _selectedItemWithFocusBackColor = Application.SystemColors.Highlight; private bool _canShowVisualStyleGlyphs = true; private AttributeCollection? _browsableAttributes; @@ -211,8 +215,8 @@ public PropertyGrid() _helpPane.TabStop = false; _helpPane.Dock = DockStyle.None; - _helpPane.BackColor = SystemColors.Control; - _helpPane.ForeColor = SystemColors.ControlText; + _helpPane.BackColor = Application.SystemColors.Control; + _helpPane.ForeColor = Application.SystemColors.ControlText; _helpPane.MouseMove += OnChildMouseMove; _helpPane.MouseDown += OnChildMouseDown; @@ -2537,6 +2541,13 @@ protected override void OnFontChanged(EventArgs e) protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); + + // Making sure, the _toolBar BackColor gets updated when the + // default BackColor is not the typical light-theme one. +#pragma warning disable CA2245 // Do not assign a property to itself + BackColor = BackColor; +#pragma warning restore CA2245 // Do not assign a property to itself + OnLayoutInternal(dividerOnly: false); TypeDescriptor.Refreshed += OnTypeDescriptorRefreshed; if (_selectedObjects is not null && _selectedObjects.Length > 0) @@ -3694,7 +3705,7 @@ private bool TryGetSavedTabIndex(out int selectedTabIndex) } private void SetHotCommandColors() - => _commandsPane.SetColors(SystemColors.Control, SystemColors.ControlText, Color.Empty, Color.Empty, Color.Empty, Color.Empty); + => _commandsPane.SetColors(SystemColors.Control, Application.SystemColors.ControlText, Color.Empty, Color.Empty, Color.Empty, Color.Empty); internal void SetStatusBox(string? title, string? description) => _helpPane.SetDescription(title, description); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/CategoryGridEntry.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/CategoryGridEntry.cs index 34fc56149cf..707c5a5f38d 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/CategoryGridEntry.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/CategoryGridEntry.cs @@ -136,8 +136,8 @@ public override void PaintLabel( Rectangle focusRect = new(indent, rect.Y, labelWidth + 3, rect.Height - 1); if (SystemInformation.HighContrast && !OwnerGrid.HasCustomLineColor) { - // Line color is SystemColors.ControlDarkDark in high contrast mode. - ControlPaint.DrawFocusRectangle(g, focusRect, SystemColors.ControlText, OwnerGrid.LineColor); + // Line color is Application.SystemColors.ControlDarkDark in high contrast mode. + ControlPaint.DrawFocusRectangle(g, focusRect, Application.SystemColors.ControlText, OwnerGrid.LineColor); } else { diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/CommandsPane.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/CommandsPane.cs index 0db69220c6b..a2a8c0e2e38 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/CommandsPane.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/CommandsPane.cs @@ -75,7 +75,7 @@ public LinkLabel Label LinkBehavior = LinkBehavior.AlwaysUnderline, // Use default LinkLabel colors for regular, active, and visited. - DisabledLinkColor = SystemColors.ControlDark + DisabledLinkColor = Application.SystemColors.ControlDark }; _label.LinkClicked += LinkClicked; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/DropDownButton.DropDownButtonAdapter.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/DropDownButton.DropDownButtonAdapter.cs index fa535aa3ff1..46aa18169f3 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/DropDownButton.DropDownButtonAdapter.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/DropDownButton.DropDownButtonAdapter.cs @@ -15,7 +15,7 @@ internal DropDownButtonAdapter(ButtonBase control) : base(control) { } private void DDB_Draw3DBorder(PaintEventArgs e, Rectangle r, bool raised) { - if (Control.BackColor != SystemColors.Control && SystemInformation.HighContrast) + if (Control.BackColor != Application.SystemColors.Control && SystemInformation.HighContrast) { if (raised) { @@ -87,7 +87,7 @@ internal override void PaintUp(PaintEventArgs pevent, CheckState state) internal override void DrawImageCore(Graphics graphics, Image image, Rectangle imageBounds, Point imageStart, LayoutData layout) { bool isHighContrastHighlighted = !Control.MouseIsDown && IsHighContrastHighlighted(); - Color backgroundColor = isHighContrastHighlighted ? SystemColors.Highlight : Control.BackColor; + Color backgroundColor = isHighContrastHighlighted ? Application.SystemColors.Highlight : Control.BackColor; if (ControlPaint.IsDark(backgroundColor) && image is Bitmap bitmap) { using Image invertedImage = ControlPaint.CreateBitmapWithInvertedForeColor(bitmap, Control.BackColor); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/PropertyGridView.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/PropertyGridView.cs index 1fc3e2bebca..0791ba2aca3 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/PropertyGridView.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/PropertyGridView.cs @@ -135,9 +135,9 @@ public PropertyGridView(IServiceProvider? serviceProvider, PropertyGrid property SetStyle(ControlStyles.ResizeRedraw, false); SetStyle(ControlStyles.UserMouse, true); - BackColor = SystemColors.Window; - ForeColor = SystemColors.WindowText; - _grayTextColor = SystemColors.GrayText; + BackColor = Application.SystemColors.Window; + ForeColor = Application.SystemColors.WindowText; + _grayTextColor = Application.SystemColors.GrayText; TabStop = true; Text = "PropertyGridView"; @@ -205,8 +205,8 @@ internal DropDownButton DropDownButton Bitmap bitmap = CreateResizedBitmap("Arrow", DownArrowIconWidth, DownArrowIconHeight); _dropDownButton.Image = bitmap; - _dropDownButton.BackColor = SystemColors.Control; - _dropDownButton.ForeColor = SystemColors.ControlText; + _dropDownButton.BackColor = Application.SystemColors.Control; + _dropDownButton.ForeColor = Application.SystemColors.ControlText; _dropDownButton.Click += OnButtonClick; _dropDownButton.GotFocus += OnDropDownButtonGotFocus; _dropDownButton.LostFocus += OnChildLostFocus; @@ -241,8 +241,8 @@ internal Button DialogButton _dialogButton = new DropDownButton { - BackColor = SystemColors.Control, - ForeColor = SystemColors.ControlText, + BackColor = Application.SystemColors.Control, + ForeColor = Application.SystemColors.ControlText, TabIndex = 3, Image = CreateResizedBitmap("dotdotdot", DotDotDotIconWidth, DotDotDotIconHeight) }; @@ -357,9 +357,9 @@ internal Color GrayTextColor return _grayTextColor; } - if (ForeColor.ToArgb() == SystemColors.WindowText.ToArgb()) + if (ForeColor.ToArgb() == Application.SystemColors.WindowText.ToArgb()) { - return SystemColors.GrayText; + return Application.SystemColors.GrayText; } // Compute the new color by halving the value of the old one. 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 d02511cad3b..59397614e25 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 @@ -169,9 +169,9 @@ public override Color BackColor get { // The tab control can only be rendered in 1 color: System's Control color. - // So, always return this value... otherwise, we're inheriting the forms backcolor + // So, always return this value... otherwise, we're inheriting the forms BackColor // and passing it on to the pab pages. - return SystemColors.Control; + return Application.SystemColors.Control; } set { @@ -1225,7 +1225,7 @@ protected override void OnHandleCreated(EventArgs e) return; } - // Add the handle to hashtable for Ids .. + // Add the handle to HashTable for Ids .. _windowId = NativeWindow.CreateWindowId(this); _handleInTable = true; @@ -1240,6 +1240,7 @@ protected override void OnHandleCreated(EventArgs e) base.OnHandleCreated(e); _cachedDisplayRect = Rectangle.Empty; ApplyItemSize(); + if (_imageList is not null) { PInvoke.SendMessage(this, PInvoke.TCM_SETIMAGELIST, 0, _imageList.Handle); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TabControl/TabPage.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TabControl/TabPage.cs index 0374f8fd402..2e5c8fcf024 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TabControl/TabPage.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TabControl/TabPage.cs @@ -101,7 +101,7 @@ public override Color BackColor { return color; } - else if (Application.RenderWithVisualStyles && UseVisualStyleBackColor && (ParentInternal is TabControl parent && parent.Appearance == TabAppearance.Normal)) + else if (!IsDarkModeEnabled && Application.RenderWithVisualStyles && UseVisualStyleBackColor && (ParentInternal is TabControl parent && parent.Appearance == TabAppearance.Normal)) { return Color.Transparent; } @@ -590,15 +590,24 @@ protected override void OnPaintBackground(PaintEventArgs e) // Utilize the UseVisualStyleBackColor property to determine whether or not the themed // background should be utilized. - if (Application.RenderWithVisualStyles && UseVisualStyleBackColor && (ParentInternal is TabControl parent && parent.Appearance == TabAppearance.Normal)) + if (Application.RenderWithVisualStyles + && UseVisualStyleBackColor + && (ParentInternal is TabControl parent && parent.Appearance == TabAppearance.Normal)) { - Color bkcolor = UseVisualStyleBackColor ? Color.Transparent : BackColor; + Color bkColor = (UseVisualStyleBackColor && !IsDarkModeEnabled) + ? Color.Transparent + : BackColor; + Rectangle inflateRect = LayoutUtils.InflateRect(DisplayRectangle, Padding); // To ensure that the TabPage draws correctly (the border will get clipped and - // and gradient fill will match correctly with the tabcontrol). Unfortunately, + // and gradient fill will match correctly with the TabControl). Unfortunately, // there is no good way to determine the padding used on the TabPage. - Rectangle rectWithBorder = new(inflateRect.X - 4, inflateRect.Y - 2, inflateRect.Width + 8, inflateRect.Height + 6); + Rectangle rectWithBorder = new( + inflateRect.X - 4, + inflateRect.Y - 2, + inflateRect.Width + 8, + inflateRect.Height + 6); TabRenderer.DrawTabPage(e, rectWithBorder); @@ -606,7 +615,14 @@ protected override void OnPaintBackground(PaintEventArgs e) // draw it ourselves. if (BackgroundImage is not null) { - ControlPaint.DrawBackgroundImage(e.Graphics, BackgroundImage, bkcolor, BackgroundImageLayout, inflateRect, inflateRect, DisplayRectangle.Location); + ControlPaint.DrawBackgroundImage( + e.Graphics, + BackgroundImage, + bkColor, + BackgroundImageLayout, + inflateRect, + inflateRect, + DisplayRectangle.Location); } } else diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TextBox/TextBox.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TextBox/TextBox.cs index 447a9dfbe77..590b4206000 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TextBox/TextBox.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TextBox/TextBox.cs @@ -907,7 +907,7 @@ private void DrawPlaceholderText(HDC hdc) } } - TextRenderer.DrawTextInternal(hdc, PlaceholderText, Font, rectangle, SystemColors.GrayText, TextRenderer.DefaultQuality, flags); + TextRenderer.DrawTextInternal(hdc, PlaceholderText, Font, rectangle, Application.SystemColors.GrayText, TextRenderer.DefaultQuality, flags); } protected override unsafe void WndProc(ref Message m) diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TextBox/TextBoxBase.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TextBox/TextBoxBase.cs index 36b068ac121..2273a8e5a91 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TextBox/TextBoxBase.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TextBox/TextBoxBase.cs @@ -285,11 +285,11 @@ public override Color BackColor } else if (ReadOnly) { - return SystemColors.Control; + return Application.SystemColors.Control; } else { - return SystemColors.Window; + return Application.SystemColors.Window; } } set => base.BackColor = value; @@ -499,7 +499,7 @@ public override Color ForeColor } else { - return SystemColors.WindowText; + return Application.SystemColors.WindowText; } } set => base.ForeColor = value; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TextBox/TextBoxRenderer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TextBox/TextBoxRenderer.cs index 95b0dfd0c57..153aae0f57e 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TextBox/TextBoxRenderer.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TextBox/TextBoxRenderer.cs @@ -28,7 +28,7 @@ private static void DrawBackground(Graphics g, Rectangle bounds, TextBoxState st if (state != TextBoxState.Disabled) { Color windowColor = t_visualStyleRenderer.GetColor(ColorProperty.FillColor); - if (windowColor != SystemColors.Window) + if (windowColor != Application.SystemColors.Window) { Rectangle fillRect = t_visualStyleRenderer.GetBackgroundContentRectangle(g, bounds); g.FillRectangle(SystemBrushes.Window, fillRect); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ProfessionalColorTable.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ProfessionalColorTable.cs index 4137a789907..306f8303c0b 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ProfessionalColorTable.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ProfessionalColorTable.cs @@ -67,7 +67,7 @@ private Dictionary ColorTable /// /// When this is specified, professional colors picks from SystemColors /// rather than colors that match the current theme. If theming is not - /// turned on, we'll fall back to SystemColors. + /// turned on, we'll fall back to Application.SystemColors. /// public bool UseSystemColors { @@ -113,13 +113,13 @@ private void ResetRGBTable() public virtual Color ButtonPressedHighlight => FromKnownColor(KnownColors.ButtonPressedHighlight); [SRDescription(nameof(SR.ProfessionalColorsButtonPressedHighlightBorderDescr))] - public virtual Color ButtonPressedHighlightBorder => SystemColors.Highlight; + public virtual Color ButtonPressedHighlightBorder => Application.SystemColors.Highlight; [SRDescription(nameof(SR.ProfessionalColorsButtonCheckedHighlightDescr))] public virtual Color ButtonCheckedHighlight => FromKnownColor(KnownColors.ButtonCheckedHighlight); [SRDescription(nameof(SR.ProfessionalColorsButtonCheckedHighlightBorderDescr))] - public virtual Color ButtonCheckedHighlightBorder => SystemColors.Highlight; + public virtual Color ButtonCheckedHighlightBorder => Application.SystemColors.Highlight; [SRDescription(nameof(SR.ProfessionalColorsButtonPressedBorderDescr))] public virtual Color ButtonPressedBorder => FromKnownColor(KnownColors.msocbvcrCBCtlBdrMouseOver); @@ -175,7 +175,7 @@ private void ResetRGBTable() public virtual Color ImageMarginGradientMiddle => FromKnownColor(KnownColors.msocbvcrCBGradVertMiddle); [SRDescription(nameof(SR.ProfessionalColorsImageMarginGradientEndDescr))] - public virtual Color ImageMarginGradientEnd => (_usingSystemColors) ? SystemColors.Control : FromKnownColor(KnownColors.msocbvcrCBGradVertEnd); + public virtual Color ImageMarginGradientEnd => (_usingSystemColors) ? Application.SystemColors.Control : FromKnownColor(KnownColors.msocbvcrCBGradVertEnd); [SRDescription(nameof(SR.ProfessionalColorsImageMarginRevealedGradientBeginDescr))] public virtual Color ImageMarginRevealedGradientBegin => FromKnownColor(KnownColors.msocbvcrCBGradMenuIconBkgdDroppedBegin); @@ -230,7 +230,7 @@ private void ResetRGBTable() [SRDescription(nameof(SR.ProfessionalColorsStatusStripBorderDescr))] // Note: the color is retained for backwards compatibility - public virtual Color StatusStripBorder => SystemColors.ButtonHighlight; + public virtual Color StatusStripBorder => Application.SystemColors.ButtonHighlight; [SRDescription(nameof(SR.ProfessionalColorsStatusStripGradientBeginDescr))] public virtual Color StatusStripGradientBegin => FromKnownColor(KnownColors.msocbvcrCBGradMainMenuHorzBegin); @@ -343,21 +343,21 @@ private static void InitCommonColors(ref Dictionary rgbTable using var screen = GdiCache.GetScreenDCGraphics(); rgbTable[KnownColors.ButtonPressedHighlight] = GetAlphaBlendedColor( screen, - SystemColors.Window, - GetAlphaBlendedColor(screen, SystemColors.Highlight, SystemColors.Window, 160), + Application.SystemColors.Window, + GetAlphaBlendedColor(screen, Application.SystemColors.Highlight, Application.SystemColors.Window, 160), 50); rgbTable[KnownColors.ButtonCheckedHighlight] = GetAlphaBlendedColor( screen, - SystemColors.Window, - GetAlphaBlendedColor(screen, SystemColors.Highlight, SystemColors.Window, 80), + Application.SystemColors.Window, + GetAlphaBlendedColor(screen, Application.SystemColors.Highlight, Application.SystemColors.Window, 80), 20); rgbTable[KnownColors.ButtonSelectedHighlight] = rgbTable[KnownColors.ButtonCheckedHighlight]; } else { - rgbTable[KnownColors.ButtonPressedHighlight] = SystemColors.Highlight; - rgbTable[KnownColors.ButtonCheckedHighlight] = SystemColors.ControlLight; - rgbTable[KnownColors.ButtonSelectedHighlight] = SystemColors.ControlLight; + rgbTable[KnownColors.ButtonPressedHighlight] = Application.SystemColors.Highlight; + rgbTable[KnownColors.ButtonCheckedHighlight] = Application.SystemColors.ControlLight; + rgbTable[KnownColors.ButtonSelectedHighlight] = Application.SystemColors.ControlLight; } } @@ -368,16 +368,16 @@ private void InitSystemColors(ref Dictionary rgbTable) InitCommonColors(ref rgbTable); // use locals so we aren't fetching again and again. - Color buttonFace = SystemColors.ButtonFace; - Color buttonShadow = SystemColors.ButtonShadow; - Color highlight = SystemColors.Highlight; - Color window = SystemColors.Window; + Color buttonFace = Application.SystemColors.ButtonFace; + Color buttonShadow = Application.SystemColors.ButtonShadow; + Color highlight = Application.SystemColors.Highlight; + Color window = Application.SystemColors.Window; Color empty = Color.Empty; - Color controlText = SystemColors.ControlText; - Color buttonHighlight = SystemColors.ButtonHighlight; - Color grayText = SystemColors.GrayText; - Color highlightText = SystemColors.HighlightText; - Color windowText = SystemColors.WindowText; + Color controlText = Application.SystemColors.ControlText; + Color buttonHighlight = Application.SystemColors.ButtonHighlight; + Color grayText = Application.SystemColors.GrayText; + Color highlightText = Application.SystemColors.HighlightText; + Color windowText = Application.SystemColors.WindowText; // initialize to high contrast Color gradientBegin = buttonFace; @@ -397,7 +397,7 @@ private void InitSystemColors(ref Dictionary rgbTable) { gradientBegin = GetAlphaBlendedColorHighRes(null, buttonFace, window, 23); gradientMiddle = GetAlphaBlendedColorHighRes(null, buttonFace, window, 50); - gradientEnd = SystemColors.ButtonFace; + gradientEnd = Application.SystemColors.ButtonFace; msocbvcrCBCtlBkgdMouseOver = GetAlphaBlendedColorHighRes(null, highlight, window, 30); msocbvcrCBCtlBkgdMouseDown = GetAlphaBlendedColorHighRes(null, highlight, window, 50); @@ -405,18 +405,18 @@ private void InitSystemColors(ref Dictionary rgbTable) if (lowResolution || highContrast) { - rgbTable[KnownColors.msocbvcrCBBkgd] = buttonFace; - rgbTable[KnownColors.msocbvcrCBCtlBkgdSelectedMouseOver] = SystemColors.ControlLight; - rgbTable[KnownColors.msocbvcrCBDragHandle] = controlText; - rgbTable[KnownColors.msocbvcrCBGradMainMenuHorzEnd] = buttonFace; - rgbTable[KnownColors.msocbvcrCBGradOptionsBegin] = buttonShadow; - rgbTable[KnownColors.msocbvcrCBGradOptionsMiddle] = buttonShadow; - rgbTable[KnownColors.msocbvcrCBGradMenuIconBkgdDroppedBegin] = buttonShadow; - rgbTable[KnownColors.msocbvcrCBGradMenuIconBkgdDroppedMiddle] = buttonShadow; - rgbTable[KnownColors.msocbvcrCBGradMenuIconBkgdDroppedEnd] = buttonShadow; - rgbTable[KnownColors.msocbvcrCBMenuBdrOuter] = controlText; - rgbTable[KnownColors.msocbvcrCBMenuBkgd] = window; - rgbTable[KnownColors.msocbvcrCBSplitterLine] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrCBBkgd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrCBCtlBkgdSelectedMouseOver] = Application.SystemColors.ControlLight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrCBDragHandle] = controlText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrCBGradMainMenuHorzEnd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrCBGradOptionsBegin] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrCBGradOptionsMiddle] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrCBGradMenuIconBkgdDroppedBegin] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrCBGradMenuIconBkgdDroppedMiddle] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrCBGradMenuIconBkgdDroppedEnd] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrCBMenuBdrOuter] = controlText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrCBMenuBkgd] = window; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrCBSplitterLine] = buttonShadow; } else { @@ -434,7 +434,7 @@ private void InitSystemColors(ref Dictionary rgbTable) rgbTable[KnownColors.msocbvcrCBSplitterLine] = GetAlphaBlendedColorHighRes(null, buttonShadow, window, 70); } - rgbTable[KnownColors.msocbvcrCBCtlBkgdSelected] = (lowResolution) ? SystemColors.ControlLight : highlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrCBCtlBkgdSelected] = (lowResolution) ? Application.SystemColors.ControlLight : highlight; rgbTable[KnownColors.msocbvcrCBBdrOuterDocked] = buttonFace; rgbTable[KnownColors.msocbvcrCBBdrOuterDocked] = buttonShadow; @@ -502,167 +502,167 @@ private void InitSystemColors(ref Dictionary rgbTable) rgbTable[KnownColors.msocbvcrCBShadow] = rgbTable[KnownColors.msocbvcrCBBkgd]; - rgbTable[KnownColors.msocbvcrCBSplitterLineLight] = buttonHighlight; - rgbTable[KnownColors.msocbvcrCBTearOffHandle] = empty; - rgbTable[KnownColors.msocbvcrCBTearOffHandleMouseOver] = empty; - rgbTable[KnownColors.msocbvcrCBTitleBkgd] = buttonShadow; - rgbTable[KnownColors.msocbvcrCBTitleText] = buttonHighlight; - rgbTable[KnownColors.msocbvcrDisabledFocuslessHighlightedText] = grayText; - rgbTable[KnownColors.msocbvcrDisabledHighlightedText] = grayText; - rgbTable[KnownColors.msocbvcrDlgGroupBoxText] = controlText; - rgbTable[KnownColors.msocbvcrDocTabBdr] = buttonShadow; - rgbTable[KnownColors.msocbvcrDocTabBdrDark] = buttonFace; - rgbTable[KnownColors.msocbvcrDocTabBdrDarkMouseDown] = highlight; - rgbTable[KnownColors.msocbvcrDocTabBdrDarkMouseOver] = SystemColors.MenuText; - rgbTable[KnownColors.msocbvcrDocTabBdrLight] = buttonFace; - rgbTable[KnownColors.msocbvcrDocTabBdrLightMouseDown] = highlight; - rgbTable[KnownColors.msocbvcrDocTabBdrLightMouseOver] = SystemColors.MenuText; - rgbTable[KnownColors.msocbvcrDocTabBdrMouseDown] = highlight; - rgbTable[KnownColors.msocbvcrDocTabBdrMouseOver] = SystemColors.MenuText; - rgbTable[KnownColors.msocbvcrDocTabBdrSelected] = buttonShadow; - rgbTable[KnownColors.msocbvcrDocTabBkgd] = buttonFace; - rgbTable[KnownColors.msocbvcrDocTabBkgdMouseDown] = highlight; - rgbTable[KnownColors.msocbvcrDocTabBkgdMouseOver] = highlight; - rgbTable[KnownColors.msocbvcrDocTabBkgdSelected] = window; - rgbTable[KnownColors.msocbvcrDocTabText] = controlText; - rgbTable[KnownColors.msocbvcrDocTabTextMouseDown] = highlightText; - rgbTable[KnownColors.msocbvcrDocTabTextMouseOver] = highlight; - rgbTable[KnownColors.msocbvcrDocTabTextSelected] = windowText; - rgbTable[KnownColors.msocbvcrDWActiveTabBkgd] = buttonFace; - rgbTable[KnownColors.msocbvcrDWActiveTabBkgd] = buttonShadow; - rgbTable[KnownColors.msocbvcrDWActiveTabText] = buttonFace; - rgbTable[KnownColors.msocbvcrDWActiveTabText] = controlText; - rgbTable[KnownColors.msocbvcrDWActiveTabTextDisabled] = buttonShadow; - rgbTable[KnownColors.msocbvcrDWActiveTabTextDisabled] = controlText; - rgbTable[KnownColors.msocbvcrDWInactiveTabBkgd] = buttonFace; - rgbTable[KnownColors.msocbvcrDWInactiveTabBkgd] = buttonShadow; - rgbTable[KnownColors.msocbvcrDWInactiveTabText] = buttonHighlight; - rgbTable[KnownColors.msocbvcrDWInactiveTabText] = controlText; - rgbTable[KnownColors.msocbvcrDWTabBkgdMouseDown] = buttonFace; - rgbTable[KnownColors.msocbvcrDWTabBkgdMouseOver] = buttonFace; - rgbTable[KnownColors.msocbvcrDWTabTextMouseDown] = controlText; - rgbTable[KnownColors.msocbvcrDWTabTextMouseOver] = controlText; - rgbTable[KnownColors.msocbvcrFocuslessHighlightedBkgd] = buttonFace; - rgbTable[KnownColors.msocbvcrFocuslessHighlightedBkgd] = SystemColors.InactiveCaption; - rgbTable[KnownColors.msocbvcrFocuslessHighlightedText] = controlText; - rgbTable[KnownColors.msocbvcrFocuslessHighlightedText] = SystemColors.InactiveCaptionText; - rgbTable[KnownColors.msocbvcrGDHeaderBdr] = highlight; - rgbTable[KnownColors.msocbvcrGDHeaderBkgd] = window; - rgbTable[KnownColors.msocbvcrGDHeaderCellBdr] = buttonShadow; - rgbTable[KnownColors.msocbvcrGDHeaderCellBkgd] = buttonFace; - rgbTable[KnownColors.msocbvcrGDHeaderCellBkgdSelected] = empty; - rgbTable[KnownColors.msocbvcrGDHeaderSeeThroughSelection] = highlight; - rgbTable[KnownColors.msocbvcrGSPDarkBkgd] = buttonFace; - rgbTable[KnownColors.msocbvcrGSPDarkBkgd] = window; - rgbTable[KnownColors.msocbvcrGSPGroupContentDarkBkgd] = window; - rgbTable[KnownColors.msocbvcrGSPGroupContentLightBkgd] = window; - rgbTable[KnownColors.msocbvcrGSPGroupContentText] = windowText; - rgbTable[KnownColors.msocbvcrGSPGroupContentTextDisabled] = grayText; - rgbTable[KnownColors.msocbvcrGSPGroupHeaderDarkBkgd] = window; - rgbTable[KnownColors.msocbvcrGSPGroupHeaderLightBkgd] = window; - rgbTable[KnownColors.msocbvcrGSPGroupHeaderText] = controlText; - rgbTable[KnownColors.msocbvcrGSPGroupHeaderText] = windowText; - rgbTable[KnownColors.msocbvcrGSPGroupline] = buttonShadow; - rgbTable[KnownColors.msocbvcrGSPGroupline] = window; - rgbTable[KnownColors.msocbvcrGSPHyperlink] = empty; - rgbTable[KnownColors.msocbvcrGSPLightBkgd] = window; - rgbTable[KnownColors.msocbvcrHyperlink] = empty; - rgbTable[KnownColors.msocbvcrHyperlinkFollowed] = empty; - rgbTable[KnownColors.msocbvcrJotNavUIBdr] = buttonShadow; - rgbTable[KnownColors.msocbvcrJotNavUIBdr] = windowText; - rgbTable[KnownColors.msocbvcrJotNavUIGradBegin] = buttonFace; - rgbTable[KnownColors.msocbvcrJotNavUIGradBegin] = window; - rgbTable[KnownColors.msocbvcrJotNavUIGradEnd] = window; - rgbTable[KnownColors.msocbvcrJotNavUIGradMiddle] = buttonFace; - rgbTable[KnownColors.msocbvcrJotNavUIGradMiddle] = window; - rgbTable[KnownColors.msocbvcrJotNavUIText] = windowText; - rgbTable[KnownColors.msocbvcrListHeaderArrow] = controlText; - rgbTable[KnownColors.msocbvcrNetLookBkgnd] = empty; - rgbTable[KnownColors.msocbvcrOABBkgd] = buttonShadow; - rgbTable[KnownColors.msocbvcrOBBkgdBdr] = buttonShadow; - rgbTable[KnownColors.msocbvcrOBBkgdBdrContrast] = window; - rgbTable[KnownColors.msocbvcrOGMDIParentWorkspaceBkgd] = buttonShadow; - rgbTable[KnownColors.msocbvcrOGRulerActiveBkgd] = window; - rgbTable[KnownColors.msocbvcrOGRulerBdr] = controlText; - rgbTable[KnownColors.msocbvcrOGRulerBkgd] = buttonFace; - rgbTable[KnownColors.msocbvcrOGRulerInactiveBkgd] = buttonShadow; - rgbTable[KnownColors.msocbvcrOGRulerTabBoxBdr] = buttonShadow; - rgbTable[KnownColors.msocbvcrOGRulerTabBoxBdrHighlight] = buttonHighlight; - rgbTable[KnownColors.msocbvcrOGRulerTabStopTicks] = buttonShadow; - rgbTable[KnownColors.msocbvcrOGRulerText] = windowText; - rgbTable[KnownColors.msocbvcrOGTaskPaneGroupBoxHeaderBkgd] = buttonFace; - rgbTable[KnownColors.msocbvcrOGWorkspaceBkgd] = buttonShadow; - rgbTable[KnownColors.msocbvcrOLKFlagNone] = buttonHighlight; - rgbTable[KnownColors.msocbvcrOLKFolderbarDark] = buttonShadow; - rgbTable[KnownColors.msocbvcrOLKFolderbarLight] = buttonShadow; - rgbTable[KnownColors.msocbvcrOLKFolderbarText] = window; - rgbTable[KnownColors.msocbvcrOLKGridlines] = buttonShadow; - rgbTable[KnownColors.msocbvcrOLKGroupLine] = buttonShadow; - rgbTable[KnownColors.msocbvcrOLKGroupNested] = buttonFace; - rgbTable[KnownColors.msocbvcrOLKGroupShaded] = buttonFace; - rgbTable[KnownColors.msocbvcrOLKGroupText] = buttonShadow; - rgbTable[KnownColors.msocbvcrOLKIconBar] = buttonFace; - rgbTable[KnownColors.msocbvcrOLKInfoBarBkgd] = buttonFace; - rgbTable[KnownColors.msocbvcrOLKInfoBarText] = controlText; - rgbTable[KnownColors.msocbvcrOLKPreviewPaneLabelText] = windowText; - rgbTable[KnownColors.msocbvcrOLKTodayIndicatorDark] = highlight; - rgbTable[KnownColors.msocbvcrOLKTodayIndicatorLight] = buttonFace; - rgbTable[KnownColors.msocbvcrOLKWBActionDividerLine] = buttonShadow; - rgbTable[KnownColors.msocbvcrOLKWBButtonDark] = buttonFace; - rgbTable[KnownColors.msocbvcrOLKWBButtonLight] = buttonFace; - rgbTable[KnownColors.msocbvcrOLKWBButtonLight] = buttonHighlight; - rgbTable[KnownColors.msocbvcrOLKWBDarkOutline] = buttonShadow; - rgbTable[KnownColors.msocbvcrOLKWBFoldersBackground] = window; - rgbTable[KnownColors.msocbvcrOLKWBHoverButtonDark] = empty; - rgbTable[KnownColors.msocbvcrOLKWBHoverButtonLight] = empty; - rgbTable[KnownColors.msocbvcrOLKWBLabelText] = windowText; - rgbTable[KnownColors.msocbvcrOLKWBPressedButtonDark] = empty; - rgbTable[KnownColors.msocbvcrOLKWBPressedButtonLight] = empty; - rgbTable[KnownColors.msocbvcrOLKWBSelectedButtonDark] = empty; - rgbTable[KnownColors.msocbvcrOLKWBSelectedButtonLight] = empty; - rgbTable[KnownColors.msocbvcrOLKWBSplitterDark] = buttonShadow; - rgbTable[KnownColors.msocbvcrOLKWBSplitterLight] = buttonFace; - rgbTable[KnownColors.msocbvcrOLKWBSplitterLight] = buttonShadow; - rgbTable[KnownColors.msocbvcrPlacesBarBkgd] = buttonFace; - rgbTable[KnownColors.msocbvcrPPOutlineThumbnailsPaneTabAreaBkgd] = buttonFace; - rgbTable[KnownColors.msocbvcrPPOutlineThumbnailsPaneTabBdr] = buttonShadow; - rgbTable[KnownColors.msocbvcrPPOutlineThumbnailsPaneTabInactiveBkgd] = buttonFace; - rgbTable[KnownColors.msocbvcrPPOutlineThumbnailsPaneTabText] = windowText; - rgbTable[KnownColors.msocbvcrPPSlideBdrActiveSelected] = highlight; - rgbTable[KnownColors.msocbvcrPPSlideBdrActiveSelectedMouseOver] = highlight; - rgbTable[KnownColors.msocbvcrPPSlideBdrInactiveSelected] = grayText; - rgbTable[KnownColors.msocbvcrPPSlideBdrMouseOver] = highlight; - rgbTable[KnownColors.msocbvcrPubPrintDocScratchPageBkgd] = buttonFace; - rgbTable[KnownColors.msocbvcrPubWebDocScratchPageBkgd] = buttonFace; - rgbTable[KnownColors.msocbvcrSBBdr] = buttonShadow; - rgbTable[KnownColors.msocbvcrScrollbarBkgd] = buttonShadow; - rgbTable[KnownColors.msocbvcrToastGradBegin] = buttonFace; - rgbTable[KnownColors.msocbvcrToastGradEnd] = buttonFace; - rgbTable[KnownColors.msocbvcrWPBdrInnerDocked] = empty; - rgbTable[KnownColors.msocbvcrWPBdrOuterDocked] = buttonFace; - rgbTable[KnownColors.msocbvcrWPBdrOuterFloating] = buttonShadow; - rgbTable[KnownColors.msocbvcrWPBkgd] = window; - rgbTable[KnownColors.msocbvcrWPCtlBdr] = buttonShadow; - rgbTable[KnownColors.msocbvcrWPCtlBdrDefault] = buttonShadow; - rgbTable[KnownColors.msocbvcrWPCtlBdrDefault] = controlText; - rgbTable[KnownColors.msocbvcrWPCtlBdrDisabled] = buttonShadow; - rgbTable[KnownColors.msocbvcrWPCtlBkgd] = buttonFace; - rgbTable[KnownColors.msocbvcrWPCtlBkgdDisabled] = buttonFace; - rgbTable[KnownColors.msocbvcrWPCtlText] = controlText; - rgbTable[KnownColors.msocbvcrWPCtlTextDisabled] = buttonShadow; - rgbTable[KnownColors.msocbvcrWPCtlTextMouseDown] = highlightText; - rgbTable[KnownColors.msocbvcrWPGroupline] = buttonShadow; - rgbTable[KnownColors.msocbvcrWPInfoTipBkgd] = SystemColors.Info; - rgbTable[KnownColors.msocbvcrWPInfoTipText] = SystemColors.InfoText; - rgbTable[KnownColors.msocbvcrWPNavBarBkgnd] = buttonFace; - rgbTable[KnownColors.msocbvcrWPText] = controlText; - rgbTable[KnownColors.msocbvcrWPText] = windowText; - rgbTable[KnownColors.msocbvcrWPTextDisabled] = grayText; - rgbTable[KnownColors.msocbvcrWPTitleBkgdActive] = highlight; - rgbTable[KnownColors.msocbvcrWPTitleBkgdInactive] = buttonFace; - rgbTable[KnownColors.msocbvcrWPTitleTextActive] = highlightText; - rgbTable[KnownColors.msocbvcrWPTitleTextInactive] = controlText; - rgbTable[KnownColors.msocbvcrXLFormulaBarBkgd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrCBSplitterLineLight] = buttonHighlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrCBTearOffHandle] = empty; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrCBTearOffHandleMouseOver] = empty; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrCBTitleBkgd] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrCBTitleText] = buttonHighlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDisabledFocuslessHighlightedText] = grayText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDisabledHighlightedText] = grayText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDlgGroupBoxText] = controlText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDocTabBdr] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDocTabBdrDark] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDocTabBdrDarkMouseDown] = highlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDocTabBdrDarkMouseOver] = Application.SystemColors.MenuText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDocTabBdrLight] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDocTabBdrLightMouseDown] = highlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDocTabBdrLightMouseOver] = Application.SystemColors.MenuText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDocTabBdrMouseDown] = highlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDocTabBdrMouseOver] = Application.SystemColors.MenuText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDocTabBdrSelected] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDocTabBkgd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDocTabBkgdMouseDown] = highlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDocTabBkgdMouseOver] = highlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDocTabBkgdSelected] = window; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDocTabText] = controlText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDocTabTextMouseDown] = highlightText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDocTabTextMouseOver] = highlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDocTabTextSelected] = windowText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDWActiveTabBkgd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDWActiveTabBkgd] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDWActiveTabText] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDWActiveTabText] = controlText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDWActiveTabTextDisabled] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDWActiveTabTextDisabled] = controlText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDWInactiveTabBkgd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDWInactiveTabBkgd] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDWInactiveTabText] = buttonHighlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDWInactiveTabText] = controlText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDWTabBkgdMouseDown] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDWTabBkgdMouseOver] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDWTabTextMouseDown] = controlText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrDWTabTextMouseOver] = controlText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrFocuslessHighlightedBkgd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrFocuslessHighlightedBkgd] = Application.SystemColors.InactiveCaption; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrFocuslessHighlightedText] = controlText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrFocuslessHighlightedText] = Application.SystemColors.InactiveCaptionText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGDHeaderBdr] = highlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGDHeaderBkgd] = window; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGDHeaderCellBdr] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGDHeaderCellBkgd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGDHeaderCellBkgdSelected] = empty; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGDHeaderSeeThroughSelection] = highlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGSPDarkBkgd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGSPDarkBkgd] = window; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGSPGroupContentDarkBkgd] = window; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGSPGroupContentLightBkgd] = window; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGSPGroupContentText] = windowText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGSPGroupContentTextDisabled] = grayText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGSPGroupHeaderDarkBkgd] = window; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGSPGroupHeaderLightBkgd] = window; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGSPGroupHeaderText] = controlText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGSPGroupHeaderText] = windowText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGSPGroupline] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGSPGroupline] = window; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGSPHyperlink] = empty; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrGSPLightBkgd] = window; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrHyperlink] = empty; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrHyperlinkFollowed] = empty; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrJotNavUIBdr] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrJotNavUIBdr] = windowText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrJotNavUIGradBegin] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrJotNavUIGradBegin] = window; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrJotNavUIGradEnd] = window; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrJotNavUIGradMiddle] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrJotNavUIGradMiddle] = window; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrJotNavUIText] = windowText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrListHeaderArrow] = controlText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrNetLookBkgnd] = empty; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOABBkgd] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOBBkgdBdr] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOBBkgdBdrContrast] = window; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOGMDIParentWorkspaceBkgd] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOGRulerActiveBkgd] = window; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOGRulerBdr] = controlText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOGRulerBkgd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOGRulerInactiveBkgd] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOGRulerTabBoxBdr] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOGRulerTabBoxBdrHighlight] = buttonHighlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOGRulerTabStopTicks] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOGRulerText] = windowText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOGTaskPaneGroupBoxHeaderBkgd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOGWorkspaceBkgd] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKFlagNone] = buttonHighlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKFolderbarDark] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKFolderbarLight] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKFolderbarText] = window; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKGridlines] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKGroupLine] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKGroupNested] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKGroupShaded] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKGroupText] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKIconBar] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKInfoBarBkgd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKInfoBarText] = controlText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKPreviewPaneLabelText] = windowText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKTodayIndicatorDark] = highlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKTodayIndicatorLight] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKWBActionDividerLine] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKWBButtonDark] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKWBButtonLight] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKWBButtonLight] = buttonHighlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKWBDarkOutline] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKWBFoldersBackground] = window; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKWBHoverButtonDark] = empty; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKWBHoverButtonLight] = empty; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKWBLabelText] = windowText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKWBPressedButtonDark] = empty; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKWBPressedButtonLight] = empty; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKWBSelectedButtonDark] = empty; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKWBSelectedButtonLight] = empty; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKWBSplitterDark] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKWBSplitterLight] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrOLKWBSplitterLight] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrPlacesBarBkgd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrPPOutlineThumbnailsPaneTabAreaBkgd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrPPOutlineThumbnailsPaneTabBdr] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrPPOutlineThumbnailsPaneTabInactiveBkgd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrPPOutlineThumbnailsPaneTabText] = windowText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrPPSlideBdrActiveSelected] = highlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrPPSlideBdrActiveSelectedMouseOver] = highlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrPPSlideBdrInactiveSelected] = grayText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrPPSlideBdrMouseOver] = highlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrPubPrintDocScratchPageBkgd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrPubWebDocScratchPageBkgd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrSBBdr] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrScrollbarBkgd] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrToastGradBegin] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrToastGradEnd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPBdrInnerDocked] = empty; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPBdrOuterDocked] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPBdrOuterFloating] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPBkgd] = window; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPCtlBdr] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPCtlBdrDefault] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPCtlBdrDefault] = controlText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPCtlBdrDisabled] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPCtlBkgd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPCtlBkgdDisabled] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPCtlText] = controlText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPCtlTextDisabled] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPCtlTextMouseDown] = highlightText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPGroupline] = buttonShadow; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPInfoTipBkgd] = Application.SystemColors.Info; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPInfoTipText] = Application.SystemColors.InfoText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPNavBarBkgnd] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPText] = controlText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPText] = windowText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPTextDisabled] = grayText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPTitleBkgdActive] = highlight; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPTitleBkgdInactive] = buttonFace; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPTitleTextActive] = highlightText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrWPTitleTextInactive] = controlText; + rgbTable[ProfessionalColorTable.KnownColors.msocbvcrXLFormulaBarBkgd] = buttonFace; } private static void InitOliveLunaColors(ref Dictionary rgbTable) diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/StatusStrip.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/StatusStrip.cs index 4af6c352791..057535e3aab 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/StatusStrip.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/StatusStrip.cs @@ -29,7 +29,11 @@ public StatusStrip() SuspendLayout(); CanOverflow = false; LayoutStyle = ToolStripLayoutStyle.Table; - RenderMode = ToolStripRenderMode.System; + + // Default changed for DarkMode from System to ManagerRenderMode. + // Also to be consistent to the MenuStrip. + // TODO: We'd need to quirk that! + RenderMode = ToolStripRenderMode.ManagerRenderMode; GripStyle = ToolStripGripStyle.Hidden; SetStyle(ControlStyles.ResizeRedraw, true); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStrip.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStrip.cs index cb64774db4f..5a2d2f4ee69 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStrip.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStrip.cs @@ -1120,6 +1120,39 @@ private CachedItemHdcInfo ItemHdcInfo } } + public Task GetGraphicsForItemAsync(ToolStripItem toolStripItem) + { + ArgumentNullException.ThrowIfNull(toolStripItem); + + TaskCompletionSource tcs = new(); + + var asyncResult = BeginInvoke(() => + { + try + { + Graphics itemGraphics; + + using Graphics toolStripGraphics = Graphics.FromHdc(Handle); + using (DeviceContextHdcScope toolStripHDC = new(toolStripGraphics, ApplyGraphicsProperties.Clipping)) + { + var itemHDC = ItemHdcInfo.GetCachedItemDC(toolStripHDC, toolStripItem.Size); + + // allocate a new graphics. + itemGraphics = itemHDC.CreateGraphics(); + } + + tcs.TrySetResult(itemGraphics); + } + catch (Exception ex) + { + tcs.TrySetException(ex); + } + }); + + EndInvoke(asyncResult); + return tcs.Task; + } + [SRCategory(nameof(SR.CatAppearance))] [SRDescription(nameof(SR.ToolStripItemRemovedDescr))] public event ToolStripItemEventHandler? ItemRemoved diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripComboBox.ToolStripComboBoxControl.ToolStripComboBoxFlatComboAdapter.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripComboBox.ToolStripComboBoxControl.ToolStripComboBoxFlatComboAdapter.cs index 155717838db..7aa33bc16f6 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripComboBox.ToolStripComboBoxControl.ToolStripComboBoxFlatComboAdapter.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripComboBox.ToolStripComboBoxControl.ToolStripComboBoxFlatComboAdapter.cs @@ -45,7 +45,7 @@ protected override Color GetOuterBorderColor(ComboBox comboBox) return base.GetOuterBorderColor(comboBox); } - return (comboBox.Enabled) ? SystemColors.Window : GetColorTable(comboBox as ToolStripComboBoxControl).ComboBoxBorder; + return (comboBox.Enabled) ? Application.SystemColors.Window : GetColorTable(comboBox as ToolStripComboBoxControl).ComboBoxBorder; } protected override Color GetPopupOuterBorderColor(ComboBox comboBox, bool focused) @@ -57,12 +57,12 @@ protected override Color GetPopupOuterBorderColor(ComboBox comboBox, bool focuse if (!comboBox.Enabled) { - return SystemColors.ControlDark; + return Application.SystemColors.ControlDark; } return focused ? GetColorTable(comboBox as ToolStripComboBoxControl).ComboBoxBorder - : SystemColors.Window; + : Application.SystemColors.Window; } protected override void DrawFlatComboDropDown(ComboBox comboBox, Graphics g, Rectangle dropDownRect) diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripDropDownButton.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripDropDownButton.cs index ffaf26309af..500aba1314a 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripDropDownButton.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripDropDownButton.cs @@ -200,11 +200,11 @@ protected override void OnPaint(PaintEventArgs e) Color arrowColor; if (Selected && !Pressed && SystemInformation.HighContrast) { - arrowColor = Enabled ? SystemColors.HighlightText : SystemColors.ControlDark; + arrowColor = Enabled ? Application.SystemColors.HighlightText : Application.SystemColors.ControlDark; } else { - arrowColor = Enabled ? SystemColors.ControlText : SystemColors.ControlDark; + arrowColor = Enabled ? Application.SystemColors.ControlText : Application.SystemColors.ControlDark; } renderer.DrawArrow(new ToolStripArrowRenderEventArgs(g, this, dropDownArrowRect, arrowColor, ArrowDirection.Down)); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripDropDownMenu.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripDropDownMenu.cs index 8f6d8dd588e..c7f8198ef76 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripDropDownMenu.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripDropDownMenu.cs @@ -565,7 +565,7 @@ protected override void OnPaintBackground(PaintEventArgs e) base.OnPaintBackground(e); if (ShowCheckMargin || ShowImageMargin) { - Renderer.DrawImageMargin(new ToolStripRenderEventArgs(e.Graphics, this, ImageMargin, SystemColors.Control)); + Renderer.DrawImageMargin(new ToolStripRenderEventArgs(e.Graphics, this, ImageMargin, Application.SystemColors.Control)); } } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripHighContrastRenderer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripHighContrastRenderer.cs index 616abadf82a..ab20fec6ad9 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripHighContrastRenderer.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripHighContrastRenderer.cs @@ -150,7 +150,7 @@ protected override void OnRenderSplitButtonBackground(ToolStripItemRenderEventAr g.DrawRectangle(SystemPens.ButtonHighlight, dropDownRect); } - Color arrowColor = item.Selected && !item.Pressed ? SystemColors.HighlightText : SystemColors.ControlText; + Color arrowColor = item.Selected && !item.Pressed ? Application.SystemColors.HighlightText : Application.SystemColors.ControlText; DrawArrow(new ToolStripArrowRenderEventArgs(g, item, dropDownRect, arrowColor, ArrowDirection.Down)); } } @@ -201,9 +201,9 @@ protected override void OnRenderOverflowButtonBackground(ToolStripItemRenderEven RenderItemInternalFilled(e, /*pressFill = */false); ToolStripItem item = e.Item; Graphics g = e.Graphics; - Color arrowColor = !item.Enabled ? SystemColors.ControlDark - : item.Selected && !item.Pressed ? SystemColors.HighlightText - : SystemColors.ControlText; + Color arrowColor = !item.Enabled ? Application.SystemColors.ControlDark + : item.Selected && !item.Pressed ? Application.SystemColors.HighlightText + : Application.SystemColors.ControlText; DrawArrow(new ToolStripArrowRenderEventArgs(g, item, new Rectangle(Point.Empty, item.Size), arrowColor, ArrowDirection.Down)); } else @@ -216,18 +216,18 @@ protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e) { if (e.Item.Selected && (!e.Item.Pressed || e.Item is ToolStripButton)) { - e.DefaultTextColor = SystemColors.HighlightText; + e.DefaultTextColor = Application.SystemColors.HighlightText; } - else if (e.TextColor != SystemColors.HighlightText && e.TextColor != SystemColors.ControlText) + else if (e.TextColor != Application.SystemColors.HighlightText && e.TextColor != Application.SystemColors.ControlText) { // we'll change the DefaultTextColor, if someone wants to change this,manually set the TextColor property. if (e.Item.Selected || e.Item.Pressed) { - e.DefaultTextColor = SystemColors.HighlightText; + e.DefaultTextColor = Application.SystemColors.HighlightText; } else { - e.DefaultTextColor = SystemColors.ControlText; + e.DefaultTextColor = Application.SystemColors.ControlText; } } @@ -240,7 +240,7 @@ protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e) ((ToolStripMenuItem)e.Item).DisplayStyle != ToolStripItemDisplayStyle.Image && ((ToolStripMenuItem)e.Item).Checked)) { - e.TextColor = SystemColors.HighlightText; + e.TextColor = Application.SystemColors.HighlightText; } base.OnRenderItemText(e); @@ -377,7 +377,7 @@ protected override void OnRenderSeparator(ToolStripSeparatorRenderEventArgs e) // Indicates whether system is currently set to high contrast 'white on black' mode internal static bool IsHighContrastWhiteOnBlack() { - return SystemColors.Control.ToArgb() == Color.Black.ToArgb(); + return Application.SystemColors.Control.ToArgb() == Color.Black.ToArgb(); } protected override void OnRenderItemImage(ToolStripItemImageRenderEventArgs e) diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripItemTextRenderEventArgs.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripItemTextRenderEventArgs.cs index c49b85f0f1b..b5cf0ff73e8 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripItemTextRenderEventArgs.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripItemTextRenderEventArgs.cs @@ -10,7 +10,7 @@ namespace System.Windows.Forms; /// public class ToolStripItemTextRenderEventArgs : ToolStripItemRenderEventArgs { - private Color _textColor = SystemColors.ControlText; + private Color _textColor = Application.SystemColors.ControlText; private bool _textColorChanged; /// diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripManager.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripManager.cs index f8b37e9aa01..a4299029886 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripManager.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripManager.cs @@ -550,12 +550,22 @@ public static bool VisualStylesEnabled internal static ToolStripRenderer CreateRenderer(ToolStripManagerRenderMode renderMode) { - return renderMode switch + switch (renderMode) { - ToolStripManagerRenderMode.System => new ToolStripSystemRenderer(isDefault: true), - ToolStripManagerRenderMode.Professional => new ToolStripProfessionalRenderer(isDefault: true), - _ => new ToolStripSystemRenderer(isDefault: true), - }; + case ToolStripManagerRenderMode.System: + return new ToolStripSystemRenderer(isDefault: true); + case ToolStripManagerRenderMode.Professional: + if (Application.IsDarkModeEnabled) + { + return new ToolStripProfessionalRenderer(new DarkProfessionalColors()); + } + + return new ToolStripProfessionalRenderer(isDefault: true); + + case ToolStripManagerRenderMode.Custom: + default: + return new ToolStripSystemRenderer(isDefault: true); + } } internal static ToolStripRenderer CreateRenderer(ToolStripRenderMode renderMode) diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripMenuItem.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripMenuItem.cs index d9c732a1ce5..beacbf9dd9d 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripMenuItem.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripMenuItem.cs @@ -725,9 +725,9 @@ private unsafe bool GetNativeMenuItemEnabled() g.DrawRectangle(SystemPens.Control, 0, 0, image.Width - 1, image.Height - 1); } - image.MakeTransparent(SystemColors.Control); - return image; - } + image.MakeTransparent(Application.SystemColors.Control); + return image; + } internal Size GetShortcutTextSize() { @@ -965,22 +965,22 @@ protected override void OnPaint(PaintEventArgs e) Graphics g = e.Graphics; renderer.DrawMenuItemBackground(new ToolStripItemRenderEventArgs(g, this)); - Color textColor = SystemColors.MenuText; - if (IsForeColorSet) - { - textColor = ForeColor; - } - else if (!IsTopLevel || (ToolStripManager.VisualStylesEnabled)) - { - if (Selected || Pressed) + Color textColor = Application.SystemColors.MenuText; + if (IsForeColorSet) { - textColor = SystemColors.HighlightText; + textColor = ForeColor; } - else + else if (!IsTopLevel || (ToolStripManager.VisualStylesEnabled)) { - textColor = SystemColors.MenuText; + if (Selected || Pressed) + { + textColor = Application.SystemColors.HighlightText; + } + else + { + textColor = Application.SystemColors.MenuText; + } } - } bool rightToLeft = (RightToLeft == RightToLeft.Yes); @@ -1017,13 +1017,13 @@ protected override void OnPaint(PaintEventArgs e) } } - if (HasDropDownItems) - { - ArrowDirection arrowDir = (rightToLeft) ? ArrowDirection.Left : ArrowDirection.Right; - Color arrowColor = (Selected || Pressed) ? SystemColors.HighlightText : SystemColors.MenuText; - arrowColor = (Enabled) ? arrowColor : SystemColors.ControlDark; - renderer.DrawArrow(new ToolStripArrowRenderEventArgs(g, this, menuItemInternalLayout.ArrowRectangle, arrowColor, arrowDir)); - } + if (HasDropDownItems) + { + ArrowDirection arrowDir = (rightToLeft) ? ArrowDirection.Left : ArrowDirection.Right; + Color arrowColor = (Selected || Pressed) ? Application.SystemColors.HighlightText : Application.SystemColors.MenuText; + arrowColor = (Enabled) ? arrowColor : Application.SystemColors.ControlDark; + renderer.DrawArrow(new ToolStripArrowRenderEventArgs(g, this, menuItemInternalLayout.ArrowRectangle, arrowColor, arrowDir)); + } if (menuItemInternalLayout.PaintImage && (DisplayStyle & ToolStripItemDisplayStyle.Image) == ToolStripItemDisplayStyle.Image && Image is not null) { diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripRenderEventArgs.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripRenderEventArgs.cs index 1d2829a65a5..39650d21a7d 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripRenderEventArgs.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripRenderEventArgs.cs @@ -62,7 +62,7 @@ public Color BackColor // get the user specified color if (ToolStrip is null) { - _backColor = SystemColors.Control; + _backColor = Application.SystemColors.Control; return _backColor; } @@ -74,15 +74,15 @@ public Color BackColor if (ToolStrip is ToolStripDropDown) { - _backColor = SystemColors.Menu; + _backColor = Application.SystemColors.Menu; } else if (ToolStrip is MenuStrip) { - _backColor = SystemColors.MenuBar; + _backColor = Application.SystemColors.MenuBar; } else { - _backColor = SystemColors.Control; + _backColor = Application.SystemColors.Control; } return _backColor; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripRenderer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripRenderer.cs index 2ac5e7b8670..468bde357a9 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripRenderer.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripRenderer.cs @@ -832,7 +832,7 @@ protected virtual void OnRenderItemCheck(ToolStripItemImageRenderEventArgs e) if (SystemInformation.HighContrast && image is Bitmap bitmap) { - Color backgroundColor = e.Item.Selected ? SystemColors.Highlight : e.Item.BackColor; + Color backgroundColor = e.Item.Selected ? Application.SystemColors.Highlight : e.Item.BackColor; if (ControlPaint.IsDark(backgroundColor)) { @@ -869,7 +869,7 @@ protected virtual void OnRenderItemText(ToolStripItemTextRenderEventArgs e) Rectangle textRect = e.TextRectangle; TextFormatFlags textFormat = e.TextFormat; // if we're disabled draw in a different color. - textColor = (item is not null && item.Enabled) ? textColor : SystemColors.GrayText; + textColor = (item is not null && item.Enabled) ? textColor : Application.SystemColors.GrayText; if (e.TextDirection != ToolStripTextDirection.Horizontal && textRect.Width > 0 && textRect.Height > 0) { diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripSeparator.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripSeparator.cs index 5154d450ef0..5d988106433 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripSeparator.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripSeparator.cs @@ -15,7 +15,7 @@ public partial class ToolStripSeparator : ToolStripItem public ToolStripSeparator() { - ForeColor = SystemColors.ControlDark; + ForeColor = Application.SystemColors.ControlDark; } [Browsable(false)] @@ -300,7 +300,7 @@ protected override void OnFontChanged(EventArgs e) } [EditorBrowsable(EditorBrowsableState.Never)] - internal override bool ShouldSerializeForeColor() => ForeColor != SystemColors.ControlDark; + internal override bool ShouldSerializeForeColor() => ForeColor != Application.SystemColors.ControlDark; protected internal override void SetBounds(Rectangle rect) { diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripSystemRenderer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripSystemRenderer.cs index 60b1e3926cf..ff62a3ae950 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripSystemRenderer.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripSystemRenderer.cs @@ -198,21 +198,21 @@ protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e) { if (DisplayInformation.HighContrast) { - FillBackground(g, bounds, SystemColors.ButtonFace); + FillBackground(g, bounds, Application.SystemColors.ButtonFace); } else if (DisplayInformation.LowResolution) { - FillBackground(g, bounds, (toolStrip is ToolStripDropDown) ? SystemColors.ControlLight : e.BackColor); + FillBackground(g, bounds, (toolStrip is ToolStripDropDown) ? Application.SystemColors.ControlLight : e.BackColor); } else if (toolStrip.IsDropDown) { FillBackground(g, bounds, (!ToolStripManager.VisualStylesEnabled) ? - e.BackColor : SystemColors.Menu); + e.BackColor : Application.SystemColors.Menu); } else if (toolStrip is MenuStrip) { FillBackground(g, bounds, (!ToolStripManager.VisualStylesEnabled) ? - e.BackColor : SystemColors.MenuBar); + e.BackColor : Application.SystemColors.MenuBar); } else if (ToolStripManager.VisualStylesEnabled && VisualStyleRenderer.IsElementDefined(VisualStyleElement.Rebar.Band.Normal)) { @@ -223,7 +223,7 @@ protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e) else { FillBackground(g, bounds, (!ToolStripManager.VisualStylesEnabled) ? - e.BackColor : SystemColors.MenuBar); + e.BackColor : Application.SystemColors.MenuBar); } } } @@ -389,7 +389,7 @@ protected override void OnRenderOverflowButtonBackground(ToolStripItemRenderEven else { RenderItemInternal(e); - Color arrowColor = item.Enabled ? SystemColors.ControlText : SystemColors.ControlDark; + Color arrowColor = item.Enabled ? Application.SystemColors.ControlText : Application.SystemColors.ControlDark; DrawArrow(new ToolStripArrowRenderEventArgs(g, item, new Rectangle(Point.Empty, item.Size), arrowColor, ArrowDirection.Down)); } } @@ -458,7 +458,7 @@ protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs } Color borderColor = ToolStripManager.VisualStylesEnabled - ? SystemColors.Highlight + ? Application.SystemColors.Highlight : ProfessionalColors.MenuItemBorder; // Draw selection border - always drawn regardless of Enabled. @@ -520,7 +520,7 @@ protected override void OnRenderSplitButtonBackground(ToolStripItemRenderEventAr Graphics g = e.Graphics; bool rightToLeft = splitButton.RightToLeft == RightToLeft.Yes; - Color arrowColor = splitButton.Enabled ? SystemColors.ControlText : SystemColors.ControlDark; + Color arrowColor = splitButton.Enabled ? Application.SystemColors.ControlText : Application.SystemColors.ControlDark; // in right to left - we need to swap the parts so we don't draw v][ toolStripSplitButton VisualStyleElement splitButtonDropDownPart = rightToLeft ? VisualStyleElement.ToolBar.SplitButton.Normal : VisualStyleElement.ToolBar.SplitButtonDropDown.Normal; @@ -648,7 +648,7 @@ private static void RenderItemInternal(ToolStripItemRenderEventArgs e) { var bounds = item.ClientBounds; bounds.Height -= 1; - ControlPaint.DrawBorderSimple(g, bounds, SystemColors.Highlight); + ControlPaint.DrawBorderSimple(g, bounds, Application.SystemColors.Highlight); } } else @@ -788,7 +788,7 @@ private static void RenderLabelInternal(ToolStripItemRenderEventArgs e) { VisualStyleRenderer? vsRenderer = VisualStyleRenderer; - if (vsRenderer is null || (item.BackColor != SystemColors.Control)) + if (vsRenderer is null || (item.BackColor != Application.SystemColors.Control)) { FillBackground(g, fillRect, item.BackColor); } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripTextBox.ToolStripTextBoxControl.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripTextBox.ToolStripTextBoxControl.cs index fb281026d80..9858f1ec947 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripTextBox.ToolStripTextBoxControl.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripTextBox.ToolStripTextBoxControl.cs @@ -245,8 +245,8 @@ private void WmNCPaint(ref Message m) if (!Enabled) { - outerBorderColor = SystemColors.ControlDark; - innerBorderColor = SystemColors.Control; + outerBorderColor = Application.SystemColors.ControlDark; + innerBorderColor = Application.SystemColors.Control; } using Graphics g = hdc.CreateGraphics(); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolstripProfessionalRenderer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolstripProfessionalRenderer.cs index 7535e6f9d86..8a2ae464859 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolstripProfessionalRenderer.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolstripProfessionalRenderer.cs @@ -300,7 +300,7 @@ protected override void OnRenderSplitButtonBackground(ToolStripItemRenderEventAr g.FillRectangle(brush, item.SplitterBounds); } - DrawArrow(new ToolStripArrowRenderEventArgs(g, item, dropDownRect, SystemColors.ControlText, ArrowDirection.Down)); + DrawArrow(new ToolStripArrowRenderEventArgs(g, item, dropDownRect, Application.SystemColors.ControlText, ArrowDirection.Down)); } protected override void OnRenderToolStripStatusLabelBackground(ToolStripItemRenderEventArgs e) @@ -564,7 +564,7 @@ protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs { if (UseSystemColors) { - borderColor = SystemColors.Highlight; + borderColor = Application.SystemColors.Highlight; RenderSelectedButtonFill(g, bounds); } else @@ -621,7 +621,7 @@ protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs { if (UseSystemColors) { - borderColor = SystemColors.Highlight; + borderColor = Application.SystemColors.Highlight; RenderSelectedButtonFill(g, bounds); } else @@ -674,7 +674,7 @@ protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e) if (item is ToolStripDropDownItem) { - e.DefaultArrowColor = item.Enabled ? SystemColors.ControlText : SystemColors.ControlDark; + e.DefaultArrowColor = item.Enabled ? Application.SystemColors.ControlText : Application.SystemColors.ControlDark; } base.OnRenderArrow(e); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TrackBar/TrackBar.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TrackBar/TrackBar.cs index 1f79acf8584..d0093827633 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TrackBar/TrackBar.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TrackBar/TrackBar.cs @@ -233,7 +233,7 @@ public override Font Font [EditorBrowsable(EditorBrowsableState.Never)] public override Color ForeColor { - get => SystemColors.WindowText; + get => Application.SystemColors.WindowText; set { } } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TreeView/TreeView.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TreeView/TreeView.cs index ed155b2e55f..81c70df4778 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TreeView/TreeView.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TreeView/TreeView.cs @@ -192,7 +192,7 @@ internal override void ReleaseUiaProvider(HWND handle) /// public override Color BackColor { - get => ShouldSerializeBackColor() ? base.BackColor : SystemColors.Window; + get => ShouldSerializeBackColor() ? base.BackColor : Application.SystemColors.Window; set { base.BackColor = value; @@ -436,7 +436,7 @@ protected override bool DoubleBuffered /// public override Color ForeColor { - get => ShouldSerializeForeColor() ? base.ForeColor : SystemColors.WindowText; + get => ShouldSerializeForeColor() ? base.ForeColor : Application.SystemColors.WindowText; set { base.ForeColor = value; @@ -1859,7 +1859,7 @@ protected override void OnHandleCreated(EventArgs e) } // Workaround for problem in TreeView where it doesn't recognize the TVS_CHECKBOXES - // style if it is set before the window is created. To get around the problem, + // style if it is set before the window is created. To get around the problem, // we set it here after the window is created, and we make sure we don't set it // in getCreateParams so that this will actually change the value of the bit. // This seems to make the TreeView happy. @@ -1878,19 +1878,19 @@ protected override void OnHandleCreated(EventArgs e) } Color c = BackColor; - if (c != SystemColors.Window) + if (c != Application.SystemColors.Window || IsDarkModeEnabled) { PInvoke.SendMessage(this, PInvoke.TVM_SETBKCOLOR, 0, c.ToWin32()); } c = ForeColor; - if (c != SystemColors.WindowText) + if (c != Application.SystemColors.WindowText || IsDarkModeEnabled) { PInvoke.SendMessage(this, PInvoke.TVM_SETTEXTCOLOR, 0, c.ToWin32()); } - // Put the linecolor into the native control only if set. + // Put the LineColor into the native control only if set. if (_lineColor != Color.Empty) { PInvoke.SendMessage(this, PInvoke.TVM_SETLINECOLOR, 0, _lineColor.ToWin32()); @@ -2641,7 +2641,10 @@ private void UpdateTreeViewExtendedStyles() // This stops the style from being removed for any derived classes that set it using P/Invoke. if (_treeViewState[TREEVIEWSTATE_doubleBufferedPropertySet]) { - PInvoke.SendMessage(this, PInvoke.TVM_SETEXTENDEDSTYLE, (WPARAM)(nint)PInvoke.TVS_EX_DOUBLEBUFFER, (LPARAM)(nint)(DoubleBuffered ? PInvoke.TVS_EX_DOUBLEBUFFER : 0)); + PInvoke.SendMessage(this, + PInvoke.TVM_SETEXTENDEDSTYLE, + (WPARAM)(nint)PInvoke.TVS_EX_DOUBLEBUFFER, + (LPARAM)(nint)(DoubleBuffered ? PInvoke.TVS_EX_DOUBLEBUFFER : 0)); } } @@ -2830,13 +2833,13 @@ private unsafe void CustomDraw(ref Message m) TreeNodeStates curState = e.State; Font font = node.NodeFont ?? node.TreeView.Font; - Color color = (((curState & TreeNodeStates.Selected) == TreeNodeStates.Selected) && node.TreeView.Focused) ? SystemColors.HighlightText : (node.ForeColor != Color.Empty) ? node.ForeColor : node.TreeView.ForeColor; + Color color = (((curState & TreeNodeStates.Selected) == TreeNodeStates.Selected) && node.TreeView.Focused) ? Application.SystemColors.HighlightText : (node.ForeColor != Color.Empty) ? node.ForeColor : node.TreeView.ForeColor; // Draw the actual node. if ((curState & TreeNodeStates.Selected) == TreeNodeStates.Selected) { g.FillRectangle(SystemBrushes.Highlight, bounds); - ControlPaint.DrawFocusRectangle(g, bounds, color, SystemColors.Highlight); + ControlPaint.DrawFocusRectangle(g, bounds, color, Application.SystemColors.Highlight); TextRenderer.DrawText(g, node.Text, font, bounds, color, TextFormatFlags.Default); } else diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/UpDown/UpDownBase.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/UpDown/UpDownBase.cs index add06a6ff4c..69d88f76938 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/UpDown/UpDownBase.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/UpDown/UpDownBase.cs @@ -578,7 +578,7 @@ protected override void OnPaint(PaintEventArgs e) // we only want to do this when BackColor is not serialized, since otherwise // we should display the backcolor instead of the usual grayed textbox. editBounds.Inflate(1, 1); - ControlPaint.DrawBorderSimple(e, editBounds, SystemColors.Control); + ControlPaint.DrawBorderSimple(e, editBounds, Application.SystemColors.Control); } } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DarkModeSettings.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DarkModeSettings.cs new file mode 100644 index 00000000000..4d02028beed --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DarkModeSettings.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Windows.Forms +{ + public enum DarkMode + { + /// + /// Dark mode in the current context is not supported. + /// + NotSupported = 0, + + /// + /// The setting for the current dark mode context is inherited from the parent context. + /// + Inherits = 1, + + /// + /// Dark mode for the current context is enabled. + /// + Enabled = 2, + + /// + /// Dark mode the current context is disabled. + /// + Disabled = 3 + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DarkProfessionalColors.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DarkProfessionalColors.cs new file mode 100644 index 00000000000..847b9654b7f --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DarkProfessionalColors.cs @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Drawing; + +namespace System.Windows.Forms +{ + internal class DarkProfessionalColors : ProfessionalColorTable + { + public override Color MenuItemPressedGradientBegin + => Color.FromArgb(0xFF, 0x60, 0x60, 0x60); + + public override Color MenuItemPressedGradientMiddle + => Color.FromArgb(0xFF, 0x60, 0x60, 0x60); + + public override Color MenuItemPressedGradientEnd + => Color.FromArgb(0xFF, 0x60, 0x60, 0x60); + + public override Color MenuItemSelected + => Application.SystemColors.ControlText; + + public override Color MenuItemSelectedGradientBegin + => Color.FromArgb(0xFF, 0x40, 0x40, 0x40); + + public override Color MenuItemSelectedGradientEnd + => Color.FromArgb(0xFF, 0x40, 0x40, 0x40); + + public override Color MenuStripGradientBegin + => Application.SystemColors.Control; + + public override Color MenuStripGradientEnd + => Application.SystemColors.Control; + + public override Color StatusStripGradientBegin + => Application.SystemColors.Control; + + public override Color StatusStripGradientEnd + => Application.SystemColors.Control; + + public override Color ToolStripDropDownBackground + => Application.SystemColors.Control; + + public override Color ImageMarginGradientBegin + => Application.SystemColors.Control; + + public override Color ImageMarginGradientMiddle + => Application.SystemColors.Control; + + public override Color ImageMarginGradientEnd + => Application.SystemColors.Control; + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Design/ComponentEditorForm.PageSelector.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Design/ComponentEditorForm.PageSelector.cs index 922705da9e7..8563332366f 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Design/ComponentEditorForm.PageSelector.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Design/ComponentEditorForm.PageSelector.cs @@ -27,7 +27,7 @@ public PageSelector() { HotTracking = true; HideSelection = false; - BackColor = SystemColors.Control; + BackColor = Application.SystemColors.Control; Indent = 0; LabelEdit = false; Scrollable = false; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Design/ComponentEditorForm.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Design/ComponentEditorForm.cs index 10b3a0d139b..be7ad5b79ff 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Design/ComponentEditorForm.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Design/ComponentEditorForm.cs @@ -195,7 +195,7 @@ private void OnConfigureUI() Label grayStrip = new Label { - BackColor = SystemColors.ControlDark + BackColor = Application.SystemColors.ControlDark }; int selectorWidth = MIN_SELECTOR_WIDTH; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Dialogs/CommonDialogs/FontDialog.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Dialogs/CommonDialogs/FontDialog.cs index 082b7d26fcc..4446391867d 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Dialogs/CommonDialogs/FontDialog.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Dialogs/CommonDialogs/FontDialog.cs @@ -96,7 +96,7 @@ public Color Color { get { - // Convert to RGB and back to resolve indirect colors like SystemColors.ControlText + // Convert to RGB and back to resolve indirect colors like Application.SystemColors.ControlText // to real color values like Color.Lime return !_usingDefaultIndirectColor ? _color : ColorTranslator.FromWin32(ColorTranslator.ToWin32(_color)); } @@ -109,7 +109,7 @@ public Color Color } else { - _color = SystemColors.ControlText; + _color = Application.SystemColors.ControlText; _usingDefaultIndirectColor = true; } } @@ -367,7 +367,7 @@ public override void Reset() { _options = CHOOSEFONT_FLAGS.CF_SCREENFONTS | CHOOSEFONT_FLAGS.CF_EFFECTS; _font = null; - _color = SystemColors.ControlText; + _color = Application.SystemColors.ControlText; _usingDefaultIndirectColor = true; ShowColor = false; _minSize = DefaultMinSize; @@ -393,7 +393,7 @@ protected override unsafe bool RunDialog(IntPtr hWndOwner) hInstance = PInvoke.GetModuleHandle((PCWSTR)null), nSizeMin = _minSize, nSizeMax = _maxSize == 0 ? int.MaxValue : _maxSize, - rgbColors = ShowColor || ShowEffects ? _color : SystemColors.ControlText + rgbColors = ShowColor || ShowEffects ? _color : Application.SystemColors.ControlText }; if (_minSize > 0 || _maxSize > 0) diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Dialogs/MessageBox.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Dialogs/MessageBox.cs index f17cc25af00..d4130928dfa 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Dialogs/MessageBox.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Dialogs/MessageBox.cs @@ -13,7 +13,7 @@ namespace System.Windows.Forms; public class MessageBox { [ThreadStatic] - private static HelpInfo[]? t_helpInfoTable; + private static HelpInfo[]? s_helpInfoTable; // This is meant to be a static class, but predates that feature. private MessageBox() @@ -27,10 +27,10 @@ internal static HelpInfo? HelpInfo // Unfortunately, there's no easy way to obtain handle of a message box. // We'll have to rely on the fact that modal message loops have to pop off in an orderly way. - if (t_helpInfoTable is not null && t_helpInfoTable.Length > 0) + if (s_helpInfoTable is not null && s_helpInfoTable.Length > 0) { // The top of the stack is actually at the end of the array. - return t_helpInfoTable[^1]; + return s_helpInfoTable[^1]; } return null; @@ -77,22 +77,22 @@ private static void PopHelpInfo() // usually there's only going to be one message box shown at a time. But if // someone shows two message boxes (say by launching them via a WM_TIMER message) // we've got to gracefully handle the current help info. - if (t_helpInfoTable is null) + if (s_helpInfoTable is null) { Debug.Fail("Why are we being called when there's nothing to pop?"); } else { - if (t_helpInfoTable.Length == 1) + if (s_helpInfoTable.Length == 1) { - t_helpInfoTable = null; + s_helpInfoTable = null; } else { - int newCount = t_helpInfoTable.Length - 1; + int newCount = s_helpInfoTable.Length - 1; HelpInfo[] newTable = new HelpInfo[newCount]; - Array.Copy(t_helpInfoTable, newTable, newCount); - t_helpInfoTable = newTable; + Array.Copy(s_helpInfoTable, newTable, newCount); + s_helpInfoTable = newTable; } } } @@ -107,20 +107,20 @@ private static void PushHelpInfo(HelpInfo hpi) int lastCount = 0; HelpInfo[] newTable; - if (t_helpInfoTable is null) + if (s_helpInfoTable is null) { newTable = new HelpInfo[lastCount + 1]; } else { // if we already have a table - allocate a new slot - lastCount = t_helpInfoTable.Length; + lastCount = s_helpInfoTable.Length; newTable = new HelpInfo[lastCount + 1]; - Array.Copy(t_helpInfoTable, newTable, lastCount); + Array.Copy(s_helpInfoTable, newTable, lastCount); } newTable[lastCount] = hpi; - t_helpInfoTable = newTable; + s_helpInfoTable = newTable; } /// @@ -413,15 +413,85 @@ public static DialogResult Show(IWin32Window? owner, string? text) return ShowCore(owner, text, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, 0, false); } - private static DialogResult ShowCore( - IWin32Window? owner, + /// + /// Displays a message box with specified text, caption, buttons, and icon asynchronously. + /// + public static Task ShowAsync( string? text, - string? caption, - MessageBoxButtons buttons, - MessageBoxIcon icon, - MessageBoxDefaultButton defaultButton, - MessageBoxOptions options, - HelpInfo hpi) + string? caption = "", + MessageBoxButtons buttons = MessageBoxButtons.OK, + MessageBoxIcon icon = MessageBoxIcon.None, + MessageBoxDefaultButton defaultButton = MessageBoxDefaultButton.Button1, + MessageBoxOptions options = MessageBoxOptions.DefaultDesktopOnly, + IWin32Window? owner = default, + string? helpFilePath = default, + HelpNavigator navigator = default, + object? param = default) + { + var tcs = new TaskCompletionSource(); + + void method() + { + try + { + DialogResult dialogResult; + + if (helpFilePath is not null) + { + var hpi = new HelpInfo(helpFilePath, navigator, param); + + dialogResult = ShowCore( + owner, + text, + caption, + buttons, + icon, + defaultButton, + options, + hpi); + + tcs.SetResult(dialogResult); + } + else + { + dialogResult = Show( + owner, + text, + caption, + buttons, + icon, + defaultButton, + options); + + tcs.SetResult(dialogResult); + } + } + catch (Exception ex) + { + tcs.SetException(ex); + } + } + + if (SynchronizationContext.Current is null) + { + WindowsFormsSynchronizationContext.InstallIfNeeded(); + } + + // Or, you can capture and use the SynchronizationContext of the UI thread + SynchronizationContext.Current!.Post(_ => method(), null); + + return tcs.Task; + } + + private static DialogResult ShowCore( + IWin32Window? owner, + string? text, + string? caption, + MessageBoxButtons buttons, + MessageBoxIcon icon, + MessageBoxDefaultButton defaultButton, + MessageBoxOptions options, + HelpInfo hpi) { DialogResult result = DialogResult.None; try diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs index 95b389b1771..895e6585226 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs @@ -11,6 +11,7 @@ using System.Windows.Forms.VisualStyles; using Windows.Win32.System.Threading; using Windows.Win32.UI.Accessibility; +using Windows.Win32.Graphics.Dwm; namespace System.Windows.Forms; @@ -160,6 +161,14 @@ public partial class Form : ContainerControl private bool _processingDpiChanged; private bool _inRecreateHandle; + public enum WindowCornerPreference + { + Default = DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_DEFAULT, + DoNotRound = DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_DONOTROUND, + Round = DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUND, + RoundSmall = DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUNDSMALL + } + /// /// Initializes a new instance of the class. /// @@ -2328,6 +2337,116 @@ protected override void SetVisibleCore(bool value) } } + /// + /// Sets the rounding style of the corners of this Form. + /// + /// + /// A value of the enum + /// which determines the corner rounding style. + /// + public void SetWindowCornerPreference(WindowCornerPreference cornerPreference) + { + SetWindowCornerPreferenceInternal(cornerPreference); + } + + private unsafe void SetWindowCornerPreferenceInternal(WindowCornerPreference cornerPreference) + { + if (!IsHandleCreated) + { + return; + } + + DWM_WINDOW_CORNER_PREFERENCE dwmCornerPreference = cornerPreference switch + { + WindowCornerPreference.Default => DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_DEFAULT, + WindowCornerPreference.DoNotRound => DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_DONOTROUND, + WindowCornerPreference.Round => DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUND, + WindowCornerPreference.RoundSmall => DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUNDSMALL, + _ => throw new ArgumentOutOfRangeException(nameof(cornerPreference)) + }; + + PInvoke.DwmSetWindowAttribute( + HWND, + DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE, + &dwmCornerPreference, + sizeof(DWM_WINDOW_CORNER_PREFERENCE)); + } + + /// + /// Sets the color of the border of this Form. + /// + /// The border color. + public void SetWindowBorderColor(Color color) + { + SetWindowBorderColorInternal(color); + } + + private unsafe void SetWindowBorderColorInternal(Color color) + { + if (!IsHandleCreated) + { + return; + } + + COLORREF colorRef = color; + + PInvoke.DwmSetWindowAttribute( + HWND, + DWMWINDOWATTRIBUTE.DWMWA_BORDER_COLOR, + &colorRef, + (uint)sizeof(COLORREF)); + } + + /// + /// Sets the color of the title bar of this Form containing the caption and control buttons. + /// + /// The title bar color. + public void SetWindowCaptionColor(Color color) + { + SetWindowCaptionColorInternal(color); + } + + private unsafe void SetWindowCaptionColorInternal(Color color) + { + if (!IsHandleCreated) + { + return; + } + + COLORREF colorRef = color; + + PInvoke.DwmSetWindowAttribute( + HWND, + DWMWINDOWATTRIBUTE.DWMWA_CAPTION_COLOR, + &colorRef, + (uint)sizeof(COLORREF)); + } + + /// + /// Sets the color of the text in the title bar of this Form. + /// + /// The text color of the title bar. + public void SetWindowCaptionTextColor(Color color) + { + SetWindowCaptionTextColorInternal(color); + } + + private unsafe void SetWindowCaptionTextColorInternal(Color color) + { + if (!IsHandleCreated) + { + return; + } + + COLORREF colorRef = color; + + PInvoke.DwmSetWindowAttribute( + HWND, + DWMWINDOWATTRIBUTE.DWMWA_TEXT_COLOR, + &colorRef, + (uint)sizeof(COLORREF)); + } + /// /// Gets or sets the form's window state. /// @@ -2719,7 +2838,8 @@ private void AdjustSystemMenu(HMENU hmenu) UpdateWindowState(); FormWindowState winState = WindowState; FormBorderStyle borderStyle = FormBorderStyle; - bool sizableBorder = borderStyle is FormBorderStyle.SizableToolWindow or FormBorderStyle.Sizable; + bool sizableBorder = (borderStyle is FormBorderStyle.SizableToolWindow + or FormBorderStyle.Sizable); bool showMin = MinimizeBox && winState != FormWindowState.Minimized; bool showMax = MaximizeBox && winState != FormWindowState.Maximized; @@ -4059,6 +4179,11 @@ protected virtual void OnLoad(EventArgs e) // Finally fire the new OnShown(unless the form has already been closed). if (IsHandleCreated) { + if (IsDarkModeEnabled) + { + PInvoke.SetWindowTheme(HWND, "DarkMode_Explorer", null); + } + BeginInvoke(new MethodInvoker(CallShownEvent)); } } @@ -5371,6 +5496,48 @@ public DialogResult ShowDialog(IWin32Window? owner) return DialogResult; } + /// + /// Shows the form as a modal dialog box asynchronously. + /// + /// A representing the outcome of the dialog. + public Task ShowDialogAsync() + { + return ShowDialogAsyncInternal(null); + } + + /// + /// Shows the form as a modal dialog box with the specified owner asynchronously. + /// + /// Any object that implements that represents the top-level window that will own the modal dialog box. + /// A representing the outcome of the dialog. + public Task ShowDialogAsync(IWin32Window owner) + { + return ShowDialogAsyncInternal(owner); + } + + private Task ShowDialogAsyncInternal(IWin32Window? owner) + { + var tcs = new TaskCompletionSource(); + + BeginInvoke(new Action(() => + { + try + { + DialogResult result = owner is null + ? ShowDialog() + : ShowDialog(owner); + + tcs.SetResult(result); + } + catch (Exception ex) + { + tcs.SetException(ex); + } + }), null); + + return tcs.Task; + } + /// /// Indicates whether the property should be /// persisted. @@ -5524,9 +5691,9 @@ protected override void UpdateDefaultButton() } } - if (containerControl.ActiveControl is IButtonControl buttonControl) + if (containerControl.ActiveControl is IButtonControl control) { - SetDefaultButton(buttonControl); + SetDefaultButton(control); } else { diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Help/Help.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Help/Help.cs index feb46335b70..a88c9316cb7 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Help/Help.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Help/Help.cs @@ -82,7 +82,7 @@ public static unsafe void ShowPopup(Control? parent, string caption, Point locat pt = location, rcMargins = new RECT(-1, -1, -1, -1), // Ignore clrForeground = new COLORREF(unchecked((uint)-1)), // Ignore - clrBackground = SystemColors.Window + clrBackground = Application.SystemColors.Window }; Font font = SystemFonts.StatusFont ?? SystemFonts.DefaultFont; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MDI/MDIClient.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MDI/MDIClient.cs index 044baf3cc0d..fbf871d2500 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/MDI/MDIClient.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/MDI/MDIClient.cs @@ -29,7 +29,7 @@ public sealed partial class MdiClient : Control public MdiClient() : base() { SetStyle(ControlStyles.Selectable, false); - BackColor = SystemColors.AppWorkspace; + BackColor = Application.SystemColors.AppWorkspace; Dock = DockStyle.Fill; } @@ -309,7 +309,10 @@ private void SetWindowRgn() } } - internal override bool ShouldSerializeBackColor() => BackColor != SystemColors.AppWorkspace; + internal override bool ShouldSerializeBackColor() + { + return BackColor != Application.SystemColors.AppWorkspace; + } private static bool ShouldSerializeLocation() => false; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Popup.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Popup.cs new file mode 100644 index 00000000000..3b39cecf5f3 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Popup.cs @@ -0,0 +1,416 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace System.Windows.Forms; + +public delegate void PopupCloseRequestEventHandler(PopupCloseRequestEventArgs e); + +[ToolboxItem(false)] +public partial class Popup : Panel, IMessageFilter +{ + private bool _isVisible; + + public event EventHandler? PopupOpening; + + public event EventHandler? PopupOpened; + + public event EventHandler? PopupClosed; + + public event EventHandler? PopupClosing; + + public event PopupCloseRequestEventHandler? PopupCloseRequested; + + private delegate bool SetForegroundWindowDelegate(IntPtr hWnd); + + private Control? _popupContentControl; + private bool _canResize; + private Control? _lastKnownAssociatingControl; + + public Popup() + { + base.AutoSize = false; + AutoSize = true; + BackColor = Color.White; + BorderStyle = BorderStyle.FixedSingle; + SetStyle(ControlStyles.ResizeRedraw, true); + SetStyle(ControlStyles.OptimizedDoubleBuffer, true); + } + + protected override CreateParams CreateParams + { + get + { + CreateParams cp = base.CreateParams; + cp.ExStyle |= (int) WINDOW_EX_STYLE.WS_EX_NOACTIVATE; + cp.Parent = IntPtr.Zero; + return cp; + } + } + + public void OpenPopup(Control associatingControl) + { + _lastKnownAssociatingControl = associatingControl; + + PopupOpeningEventArgs e = new PopupOpeningEventArgs(false, Size.Empty); + OnPopupOpening(e); + + if (e.Cancel) + { + return; + } + + Show(associatingControl); + OnPopupOpened(EventArgs.Empty); + } + + public void ClosePopup() + { + ClosePopupInternally(new PopupCloseRequestEventArgs(PopupCloseRequestReason.CloseMethodInvoked)); + } + + internal void ClosePopupInternally(PopupCloseRequestEventArgs ClosingReason) + { + if (ClosingReason.ClosingRequestOrigin == PopupCloseRequestOrigin.ExternalByUser) + { + ClosingReason.ClosingRequestOrigin = PopupCloseRequestOrigin.InternalByComponent; + OnPopupClosing(ClosingReason); + } + + if (!IsOpen) + { + return; + } + + if (!ClosingReason.Cancel) + { + Hide(); + OnPopupClosed(EventArgs.Empty); + } + } + + private void Show(Control referringControl) + { + Location = GetPopupLocation(referringControl, Size); + + PInvoke.SetParent((HWND)Handle, HWND.Null); + PInvoke.ShowWindow((HWND)Handle, (SHOW_WINDOW_CMD)1); + PInvoke.SetForegroundWindow((HWND)Handle); + + Application.AddMessageFilter(this); + + _isVisible = true; + } + + private new void Hide() + { + if (!_isVisible) + { + return; + } + + PInvoke.ShowWindow((HWND)Handle, 0); + _isVisible = false; + } + + bool IMessageFilter.PreFilterMessage(ref Message m) + { + // Check if the control is disposed + if (IsDisposed) + { + return false; + } + + // Handle mouse left-button down events inside the control hierarchy + if (_lastKnownAssociatingControl is not null + && m.Msg == PInvoke.WM_LBUTTONDOWN + && IsHandleInHierarchy(_lastKnownAssociatingControl, m.HWnd) + && IsOpen) + { + return false; + } + + // Handle the Escape key to close the popup + if (m.Msg == PInvoke.WM_KEYDOWN && m.WParamInternal == (int)Keys.Escape && IsOpen) + { + var e = new PopupCloseRequestEventArgs(PopupCloseRequestReason.Keyboard) + { + KeyData = Keys.Escape + }; + + PopupCloseRequested?.Invoke(e); + return true; + } + + // Handle the Enter key to commit the popup + if (m.Msg == PInvoke.WM_KEYDOWN && m.WParamInternal == (int)Keys.Return && IsOpen) + { + var e = new PopupCloseRequestEventArgs(PopupCloseRequestReason.Keyboard) + { + KeyData = Keys.Return + }; + + PopupCloseRequested?.Invoke(e); + return true; + } + + // Handle the Tab key for navigation + if (m.Msg == PInvoke.WM_KEYDOWN && m.WParamInternal == (int)Keys.Tab && IsOpen) + { + var e = new PopupCloseRequestEventArgs(PopupCloseRequestReason.Keyboard) + { + KeyData = Keys.Tab + }; + PopupCloseRequested?.Invoke(e); + + return false; + } + + PopupCloseRequestEventArgs? popupClosingEventArgs = null; + + // Handle if the application loses focus + if (_isVisible && (Form.ActiveForm is null || Form.ActiveForm.Equals(this))) + { + popupClosingEventArgs = new PopupCloseRequestEventArgs(PopupCloseRequestReason.AppLostFocus); + } + + // Handle mouse clicks outside of this control hierarchy + if ((m.Msg == PInvoke.WM_LBUTTONDOWN || m.Msg == PInvoke.WM_NCLBUTTONDOWN) + && !IsHandleInHierarchy(m.HWnd)) + { + popupClosingEventArgs = new PopupCloseRequestEventArgs(PopupCloseRequestReason.PopupLostFocus); + } + + // Trigger the closing event if applicable + if (popupClosingEventArgs is not null) + { + if (IsOpen) + { + OnPopupClosing(popupClosingEventArgs); + } + } + + return false; + } + + internal bool IsHandleInHierarchy(IntPtr hwnd) + { + return IsHandleInHierarchy(this, hwnd); + } + + internal static bool IsHandleInHierarchy(Control? ctrl, IntPtr hwnd) + { + if (ctrl is null) + { + return false; + } + + if (hwnd == ctrl.Handle) + { + return true; + } + + IntPtr currentParentHwnd = hwnd; + IntPtr parentHwnd = PInvoke.GetParent((HWND)currentParentHwnd); + + if (parentHwnd == IntPtr.Zero) + { + return false; + } + + do + { + parentHwnd = PInvoke.GetParent((HWND)currentParentHwnd); + + if (parentHwnd == ctrl.Handle) + { + return true; + } + + if (parentHwnd == IntPtr.Zero) + { + return false; + } + + currentParentHwnd = parentHwnd; + } + + while (true); + } + + private Rectangle BottomGripArea + { + get + { + Rectangle rect = ClientRectangle; + rect.Y = rect.Bottom - 4; + rect.Height = 4; + return rect; + } + } + + private Rectangle RightGripArea + { + get + { + Rectangle rect = ClientRectangle; + rect.X = rect.Width - 10; + rect.Width = 10; + return rect; + } + } + + protected override void WndProc(ref Message m) + { + if (CanResize) + { + if (m.Msg == PInvoke.WM_GETMINMAXINFO) + { + object? nullableMinMaxInfo = Marshal.PtrToStructure(m.LParamInternal, typeof(MINMAXINFO)); + + if (nullableMinMaxInfo is not null) + { + MINMAXINFO minMaxInfo = (MINMAXINFO)nullableMinMaxInfo; + minMaxInfo.ptMinTrackSize.X = MinimumSize.Width; + minMaxInfo.ptMinTrackSize.Y = MinimumSize.Height; + + if (!(MaximumSize.Width == 0 && MaximumSize.Height == 0)) + { + minMaxInfo.ptMaxTrackSize.X = MaximumSize.Width; + minMaxInfo.ptMaxTrackSize.Y = MaximumSize.Height; + } + + Marshal.StructureToPtr(minMaxInfo, m.LParamInternal, true); + } + } + else if (m.Msg == PInvoke.WM_NCHITTEST) + { + int x = m.LParamInternal.LOWORD; + int y = m.LParamInternal.HIWORD; + + Point cLoc = PointToClient(new Point(x, y)); + + if (BottomGripArea.Contains(cLoc) && !RightGripArea.Contains(cLoc)) + { + m.ResultInternal = new LRESULT((nint)PInvoke.HTBOTTOM); + return; + } + + if (RightGripArea.Contains(cLoc)) + { + m.ResultInternal = new LRESULT((nint)PInvoke.HTBOTTOMRIGHT); + return; + } + } + } + + base.WndProc(ref m); + } + + public bool CanResize + { + get => _canResize; + + set + { + AutoSize = !value; + _canResize = value; + } + } + + public Control? PopupContent + { + get => _popupContentControl; + + set + { + if (_popupContentControl == value) + { + return; + } + + _popupContentControl = value; + + if (_popupContentControl is null) + { + return; + } + + if (typeof(Form).IsAssignableFrom(_popupContentControl.GetType())) + { + ((Form)_popupContentControl).TopLevel = false; + _popupContentControl.Dock = DockStyle.Fill; + } + + SuspendLayout(); + Controls.Add(PopupContent); + ResumeLayout(true); + } + } + + public bool IsOpen => _isVisible; + + protected virtual void OnPopupOpening(PopupOpeningEventArgs e) + { + PopupOpening?.Invoke(this, e); + + if (e.Cancel) + { + return; + } + + if (!e.PreferredNewSize.IsEmpty) + { + Size = e.PreferredNewSize; + if (e.PreventResizing) + { + MaximumSize = e.PreferredNewSize; + MinimumSize = e.PreferredNewSize; + } + } + } + + private void OnPopupOpened(EventArgs e) + => PopupOpened?.Invoke(this, e); + + protected virtual void OnPopupClosing(PopupCloseRequestEventArgs e) + => PopupClosing?.Invoke(this, e); + + protected virtual void OnPopupClosed(EventArgs e) + { + PopupClosed?.Invoke(this, e); + _lastKnownAssociatingControl = null; + } + + public static Point GetPopupLocation(Control referringControl, Size popupSize) + { + Point screenCoordinates; + + if (referringControl.Parent is null) + { + throw new InvalidOperationException("Control must be assigned to a Form when calculating the screen coordinates for its popup position"); + } + + screenCoordinates = referringControl.Parent.PointToScreen(referringControl.Location); + screenCoordinates += new Size(0, referringControl.Height); + + var currentScreen = Screen.FromPoint(screenCoordinates).WorkingArea; + Rectangle tmpRec = new Rectangle(screenCoordinates, popupSize); + + if (currentScreen.Y + currentScreen.Height < tmpRec.Bottom) + { + screenCoordinates = referringControl.Parent.PointToScreen(referringControl.Location); + screenCoordinates -= new Size(0, popupSize.Height); + } + + if (currentScreen.X + currentScreen.Width < tmpRec.Right) + { + screenCoordinates -= new Size(popupSize.Width - referringControl.Width, 0); + } + + return screenCoordinates; + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/PopupCloseRequestEventArgs.cs b/src/System.Windows.Forms/src/System/Windows/Forms/PopupCloseRequestEventArgs.cs new file mode 100644 index 00000000000..cc259841005 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/PopupCloseRequestEventArgs.cs @@ -0,0 +1,55 @@ +using System.ComponentModel; + +namespace System.Windows.Forms; + +/// +/// Represents the event data for a popup closing event. +/// +public class PopupCloseRequestEventArgs : CancelEventArgs +{ + /// + /// Initializes a new instance of the class. + /// + /// The reason why the popup is closing. + public PopupCloseRequestEventArgs(PopupCloseRequestReason closeReason) + { + PopupClosingRequestReason = closeReason; + KeyData = Keys.None; + } + + /// + /// Initializes a new instance of the class. + /// + /// The reason why the popup is closing. + /// The key data associated with the popup closing event. + public PopupCloseRequestEventArgs(PopupCloseRequestReason closingRequestReason, Keys keyData) + { + PopupClosingRequestReason = closingRequestReason; + KeyData = keyData; + } + + /// + /// Gets or sets the reason why the popup is closing. + /// + /// + /// The reason why the popup is closing represented by a value. + /// + public PopupCloseRequestReason PopupClosingRequestReason { get; set; } + + /// + /// Gets or sets the key data associated with the popup closing event. + /// + /// + /// The key data associated with the popup closing event. + /// + public Keys KeyData { get; set; } + + /// + /// Gets or sets the cause of the popup closing event. + /// + /// + /// The request original of the popup closing event, which can be + /// or ."/> + /// + public PopupCloseRequestOrigin ClosingRequestOrigin { get; set; } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/PopupCloseRequestOrigin.cs b/src/System.Windows.Forms/src/System/Windows/Forms/PopupCloseRequestOrigin.cs new file mode 100644 index 00000000000..d9ef0cb8909 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/PopupCloseRequestOrigin.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Windows.Forms; + +/// +/// Represents the closing request origin in the context of the . +/// +public enum PopupCloseRequestOrigin +{ + /// + /// An action by the user caused the popup to close. + /// + ExternalByUser = 0, + + /// + /// The popup was closed by the component itself. + /// + InternalByComponent = 1 +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/PopupCloseRequestReason.cs b/src/System.Windows.Forms/src/System/Windows/Forms/PopupCloseRequestReason.cs new file mode 100644 index 00000000000..b77c1b66b6d --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/PopupCloseRequestReason.cs @@ -0,0 +1,32 @@ +namespace System.Windows.Forms; + +/// +/// Represents the closing request reason in the context of the the . +/// +public enum PopupCloseRequestReason +{ + /// + /// The popup was closed because another part of the surface was clicked, which caused the popup to close. + /// + PopupLostFocus = 0, + + /// + /// The application was put in the background because another application was switched to. + /// + AppLostFocus = 1, + + /// + /// The popup's Close method was invoked. + /// + CloseMethodInvoked = 2, + + /// + /// Some content of the popup was clicked. + /// + ContentClicked = 3, + + /// + /// The popup was closed by a corresponding keyboard functionality. + /// + Keyboard = 4, +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/PopupOpeningEventArgs.cs b/src/System.Windows.Forms/src/System/Windows/Forms/PopupOpeningEventArgs.cs new file mode 100644 index 00000000000..7693f0090c8 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/PopupOpeningEventArgs.cs @@ -0,0 +1,38 @@ +using System.ComponentModel; +using System.Drawing; + +namespace System.Windows.Forms; + +/// +/// Represents the event data for a popup opening event. +/// +/// +public class PopupOpeningEventArgs : CancelEventArgs +{ + /// + /// Initializes a new instance of the class. + /// + /// true if the event should be canceled; otherwise, false. + /// The preferred new size of the popup. + public PopupOpeningEventArgs(bool cancel, Size preferredNewSize) + { + base.Cancel = cancel; + PreferredNewSize = preferredNewSize; + } + + /// + /// Gets or sets the preferred new size of the popup. + /// + /// + /// The preferred new size of the popup. + /// + public Size PreferredNewSize { get; set; } + + /// + /// Gets or sets a value indicating whether the popup is should be prevented from resizing. + /// + /// + /// if the popup is should not be resized; otherwise, . + /// + public bool PreventResizing { get; set; } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Printing/PrintPreviewControl.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Printing/PrintPreviewControl.cs index 5f29bc722df..f8a053d5f31 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Printing/PrintPreviewControl.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Printing/PrintPreviewControl.cs @@ -290,7 +290,7 @@ public override string Text } [EditorBrowsable(EditorBrowsableState.Never)] - public override void ResetBackColor() => BackColor = SystemColors.AppWorkspace; + public override void ResetBackColor() => BackColor = Application.SystemColors.AppWorkspace; internal override bool ShouldSerializeBackColor() => !BackColor.Equals(SystemColors.AppWorkspace); @@ -717,7 +717,7 @@ private void PaintFocus(PaintEventArgs e, bool isHighContrast) if (isHighContrast) { - ControlPaint.DrawHighContrastFocusRectangle(e.Graphics, focusRect, SystemColors.ControlText); + ControlPaint.DrawHighContrastFocusRectangle(e.Graphics, focusRect, Application.SystemColors.ControlText); } else { @@ -737,7 +737,7 @@ private void PaintFocus(PaintEventArgs e, bool isHighContrast) /// private Color GetBackColor(bool isHighContract) { - return (isHighContract && !ShouldSerializeBackColor()) ? SystemColors.ControlDark : BackColor; + return (isHighContract && !ShouldSerializeBackColor()) ? Application.SystemColors.ControlDark : BackColor; } private static int PixelsToPhysical(int pixels, int dpi) => (int)(pixels * 100.0 / dpi); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/AsyncGraphicsFactory.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/AsyncGraphicsFactory.cs new file mode 100644 index 00000000000..532a8968bcb --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/AsyncGraphicsFactory.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Drawing; + +namespace System.Windows.Forms; + +/// +/// Allows for the acquiring of objects in async scenarios. +/// +public class AsyncGraphicsFactory +{ + private readonly IntPtr _hdc; + + internal AsyncGraphicsFactory(IntPtr hdc) + { + _hdc = hdc; + } + + /// + /// Allows to acquire objects for async scenarios. Note that you cannot use the Graphics object of the , + /// since it is getting disposed when the scope of the proc has been exited. + /// + /// + public Task GetGraphicsAsync() + { + Graphics graphics = Graphics.FromHdc(_hdc); + return Task.FromResult(graphics); + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/ControlPaint.HLSColor.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/ControlPaint.HLSColor.cs index 1396db75bcc..0b6eda07c8d 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/ControlPaint.HLSColor.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/ControlPaint.HLSColor.cs @@ -26,7 +26,7 @@ public static partial class ControlPaint public HLSColor(Color color) { - _isSystemColors_Control = color.ToKnownColor() == SystemColors.Control.ToKnownColor(); + _isSystemColors_Control = color.ToKnownColor() == Application.SystemColors.Control.ToKnownColor(); ARGB argb = color; int r = argb.R; @@ -100,16 +100,16 @@ public Color Darker(float percDarker) // what we would otherwise calculate if (percDarker == 0.0f) { - return SystemColors.ControlDark; + return Application.SystemColors.ControlDark; } else if (percDarker == 1.0f) { - return SystemColors.ControlDarkDark; + return Application.SystemColors.ControlDarkDark; } else { - ARGB dark = SystemColors.ControlDark; - ARGB darkDark = SystemColors.ControlDarkDark; + ARGB dark = Application.SystemColors.ControlDark; + ARGB darkDark = Application.SystemColors.ControlDarkDark; return Color.FromArgb( (byte)(dark.R - (byte)((dark.R - darkDark.R) * percDarker)), @@ -151,16 +151,16 @@ public Color Lighter(float percentLighter) // what we would otherwise calculate if (percentLighter == 0.0f) { - return SystemColors.ControlLight; + return Application.SystemColors.ControlLight; } else if (percentLighter == 1.0f) { - return SystemColors.ControlLightLight; + return Application.SystemColors.ControlLightLight; } else { - ARGB light = SystemColors.ControlLight; - ARGB lightLight = SystemColors.ControlLightLight; + ARGB light = Application.SystemColors.ControlLight; + ARGB lightLight = Application.SystemColors.ControlLightLight; return Color.FromArgb( (byte)(light.R - (byte)((light.R - lightLight.R) * percentLighter)), diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/ControlPaint.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/ControlPaint.cs index 9cdb3652a1c..2af3550544e 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/ControlPaint.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/ControlPaint.cs @@ -137,7 +137,7 @@ internal static Rectangle CalculateBackgroundImageRectangle(Rectangle bounds, Si /// which ControlDark does not work in high contrast color schemes. /// public static Color ContrastControlDark - => SystemInformation.HighContrast ? SystemColors.WindowFrame : SystemColors.ControlDark; + => SystemInformation.HighContrast ? Application.SystemColors.WindowFrame : Application.SystemColors.ControlDark; /// /// Creates a 16-bit color bitmap. @@ -1081,7 +1081,7 @@ private static void DrawBorderComplex(Graphics graphics, Rectangle bounds, Color graphics.DrawLine(mediumPen, bounds.X + 1, bounds.Y + 1, bounds.X + 1, bounds.Y + bounds.Height - 2); // Bottom + right inset - if (color.ToKnownColor() == SystemColors.Control.ToKnownColor()) + if (color.ToKnownColor() == Application.SystemColors.Control.ToKnownColor()) { Pen pen = SystemPens.ControlLight; graphics.DrawLine( @@ -1097,16 +1097,16 @@ private static void DrawBorderComplex(Graphics graphics, Rectangle bounds, Color // Standard button Debug.Assert(style == ButtonBorderStyle.Outset, "Caller should have known how to use us."); - bool stockColor = color.ToKnownColor() == SystemColors.Control.ToKnownColor(); + bool stockColor = color.ToKnownColor() == Application.SystemColors.Control.ToKnownColor(); HLSColor hls = new(color); // Top + left - using var lightPen = (stockColor ? SystemColors.ControlLightLight : hls.Lighter(1.0f)).GetCachedPenScope(); + using var lightPen = (stockColor ? Application.SystemColors.ControlLightLight : hls.Lighter(1.0f)).GetCachedPenScope(); graphics.DrawLine(lightPen, bounds.X, bounds.Y, bounds.X + bounds.Width - 1, bounds.Y); graphics.DrawLine(lightPen, bounds.X, bounds.Y, bounds.X, bounds.Y + bounds.Height - 1); // Bottom + right - using var darkPen = (stockColor ? SystemColors.ControlDarkDark : hls.Darker(1.0f)).GetCachedPenScope(); + using var darkPen = (stockColor ? Application.SystemColors.ControlDarkDark : hls.Darker(1.0f)).GetCachedPenScope(); graphics.DrawLine( darkPen, @@ -1119,14 +1119,14 @@ private static void DrawBorderComplex(Graphics graphics, Rectangle bounds, Color using var topLeftPen = (!stockColor ? color : SystemInformation.HighContrast - ? SystemColors.ControlLightLight - : SystemColors.Control).GetCachedPenScope(); + ? Application.SystemColors.ControlLightLight + : Application.SystemColors.Control).GetCachedPenScope(); graphics.DrawLine(topLeftPen, bounds.X + 1, bounds.Y + 1, bounds.X + bounds.Width - 2, bounds.Y + 1); graphics.DrawLine(topLeftPen, bounds.X + 1, bounds.Y + 1, bounds.X + 1, bounds.Y + bounds.Height - 2); // Bottom + right inset - using var bottomRightPen = (stockColor ? SystemColors.ControlDark : hls.Darker(0.5f)).GetCachedPenScope(); + using var bottomRightPen = (stockColor ? Application.SystemColors.ControlDark : hls.Darker(0.5f)).GetCachedPenScope(); graphics.DrawLine( bottomRightPen, @@ -1324,8 +1324,8 @@ private static void DrawFlatCheckBox(Graphics graphics, Rectangle rectangle, But ? SystemBrushes.Control : SystemBrushes.Window; Color foreground = ((state & ButtonState.Inactive) == ButtonState.Inactive) - ? (SystemInformation.HighContrast ? SystemColors.GrayText : SystemColors.ControlDark) - : SystemColors.ControlText; + ? (SystemInformation.HighContrast ? Application.SystemColors.GrayText : Application.SystemColors.ControlDark) + : Application.SystemColors.ControlText; DrawFlatCheckBox(graphics, rectangle, foreground, background, state); } @@ -1395,7 +1395,7 @@ private static void DrawFlatCheckBox( /// control has the current keyboard focus. /// public static void DrawFocusRectangle(Graphics graphics, Rectangle rectangle) - => DrawFocusRectangle(graphics, rectangle, SystemColors.ControlText, SystemColors.Control); + => DrawFocusRectangle(graphics, rectangle, Application.SystemColors.ControlText, Application.SystemColors.Control); /// /// Draws a focus rectangle. A focus rectangle is a dotted rectangle that Windows uses to indicate what @@ -2001,7 +2001,7 @@ internal static void DrawStringDisabled( { if (SystemInformation.HighContrast) { - TextRenderer.DrawTextInternal(dc, s, font, layoutRectangle, SystemColors.GrayText, quality, format); + TextRenderer.DrawTextInternal(dc, s, font, layoutRectangle, Application.SystemColors.GrayText, quality, format); } else { @@ -2079,7 +2079,7 @@ private static int GetColorRop(Color color, int darkROP, int lightROP) /// private static Brush GetActiveBrush(Color backColor) { - Color brushColor = backColor.GetBrightness() <= .5 ? SystemColors.ControlLight : SystemColors.ControlDark; + Color brushColor = backColor.GetBrightness() <= .5 ? Application.SystemColors.ControlLight : Application.SystemColors.ControlDark; if (t_frameBrushActive is null || !s_frameColorActive.Equals(brushColor)) { @@ -2209,7 +2209,7 @@ private static Pen GetFocusPen(Color baseColor, bool odds, bool highContrast, bo /// private static Brush GetSelectedBrush(Color backColor) { - Color brushColor = backColor.GetBrightness() <= .5 ? SystemColors.ControlLight : SystemColors.ControlDark; + Color brushColor = backColor.GetBrightness() <= .5 ? Application.SystemColors.ControlLight : Application.SystemColors.ControlDark; if (t_frameBrushSelected is null || !s_frameColorSelected.Equals(brushColor)) { diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/DrawItemEventArgs.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/DrawItemEventArgs.cs index 5812ded87b3..81c485107e1 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/DrawItemEventArgs.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/DrawItemEventArgs.cs @@ -29,7 +29,7 @@ public class DrawItemEventArgs : EventArgs, IDisposable, IDeviceContext, IGraphi /// Creates a new DrawItemEventArgs with the given parameters. /// public DrawItemEventArgs(Graphics graphics, Font? font, Rectangle rect, int index, DrawItemState state) - : this(graphics, font, rect, index, state, SystemColors.WindowText, SystemColors.Window) + : this(graphics, font, rect, index, state, Application.SystemColors.WindowText, Application.SystemColors.Window) { } /// @@ -59,7 +59,7 @@ internal DrawItemEventArgs( Rectangle rect, uint index, ODS_FLAGS state) - : this(hdc, font, rect, index, state, SystemColors.WindowText, SystemColors.Window) + : this(hdc, font, rect, index, state, Application.SystemColors.WindowText, Application.SystemColors.Window) { } internal DrawItemEventArgs( @@ -108,14 +108,14 @@ internal DrawItemEventArgs( public DrawItemState State { get; } /// - /// A suggested color drawing: either SystemColors.WindowText or SystemColors.HighlightText, + /// A suggested color drawing: either Application.SystemColors.WindowText or Application.SystemColors.HighlightText, /// depending on whether this item is selected. /// public Color ForeColor - => (State & DrawItemState.Selected) == DrawItemState.Selected ? SystemColors.HighlightText : _foreColor; + => (State & DrawItemState.Selected) == DrawItemState.Selected ? Application.SystemColors.HighlightText : _foreColor; public Color BackColor - => (State & DrawItemState.Selected) == DrawItemState.Selected ? SystemColors.Highlight : _backColor; + => (State & DrawItemState.Selected) == DrawItemState.Selected ? Application.SystemColors.Highlight : _backColor; /// /// Fills the with the . diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/PaintEventArgs.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/PaintEventArgs.cs index ba9f0ac5ff6..5a4164cbeb3 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/PaintEventArgs.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/PaintEventArgs.cs @@ -33,6 +33,7 @@ public partial class PaintEventArgs : EventArgs, IDisposable, IDeviceContext, IG /// /// private GraphicsState? _savedGraphicsState; + private readonly AsyncGraphicsFactory _graphicsFactory; public PaintEventArgs(Graphics graphics, Rectangle clipRect) : this( graphics, @@ -47,6 +48,7 @@ internal PaintEventArgs( Rectangle clipRect) { HDC hdc = e.HDC; + _graphicsFactory = new AsyncGraphicsFactory(hdc); _event = hdc.IsNull ? new DrawingEventArgs(e.GraphicsInternal, clipRect, e._event.Flags) : new DrawingEventArgs(hdc, clipRect, e._event.Flags); @@ -58,6 +60,7 @@ internal PaintEventArgs( DrawingEventFlags flags) { _event = new DrawingEventArgs(graphics, clipRect, flags); + _graphicsFactory = new AsyncGraphicsFactory(_event.HDC); SaveStateIfNeeded(graphics); } @@ -70,6 +73,7 @@ internal PaintEventArgs( DrawingEventFlags flags = DrawingEventFlags.CheckState) { _event = new DrawingEventArgs(hdc, clipRect, flags); + _graphicsFactory = new AsyncGraphicsFactory(hdc); } ~PaintEventArgs() => Dispose(false); @@ -84,6 +88,8 @@ internal PaintEventArgs( /// public Graphics Graphics => _event.Graphics; + public AsyncGraphicsFactory GraphicsFactory => _graphicsFactory; + /// /// Disposes of the resources (other than memory) used by the . /// diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/TextRenderer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/TextRenderer.cs index 0f5f47c1a64..e556bec4481 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/TextRenderer.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Rendering/TextRenderer.cs @@ -549,15 +549,15 @@ internal static Color DisabledTextColor(Color backColor) { if (SystemInformation.HighContrast) { - return SystemColors.GrayText; + return Application.SystemColors.GrayText; } - // If the color is darker than SystemColors.Control make it slightly darker, + // If the color is darker than Application.SystemColors.Control make it slightly darker, // otherwise use the standard control dark color. - return ControlPaint.IsDarker(backColor, SystemColors.Control) + return ControlPaint.IsDarker(backColor, Application.SystemColors.Control) ? ControlPaint.Dark(backColor) - : SystemColors.ControlDark; + : Application.SystemColors.ControlDark; } /// @@ -620,27 +620,28 @@ internal static ApplyGraphicsProperties GetApplyStateFlags(IDeviceContext device #if DEBUG if ((textFormatFlags & SkipAssertFlag) == 0) { - // Clipping and translation transforms applied to Graphics objects are not done on the underlying HDC. - // When we're rendering text to the HDC we, by default, should apply both. If it is *known* that these - // aren't wanted we can get a _slight_ performance benefit by not applying them and in that case the - // SkipAssertFlag bit can be set to skip this check. - // - // This application of clipping and translation is meant to make Graphics.DrawText and TextRenderer.DrawText - // roughly equivalent in the way they render. - // - // Note that there aren't flags for other transforms. Windows 9x doesn't support HDC transforms outside of - // translation (rotation for example), and this likely impacted the decision to only have a translation - // flag when this was originally written. + //// Clipping and translation transforms applied to Graphics objects are not done on the underlying HDC. + //// When we're rendering text to the HDC we, by default, should apply both. If it is *known* that these + //// aren't wanted we can get a _slight_ performance benefit by not applying them and in that case the + //// SkipAssertFlag bit can be set to skip this check. + //// + //// This application of clipping and translation is meant to make Graphics.DrawText and TextRenderer.DrawText + //// roughly equivalent in the way they render. + //// + //// Note that there aren't flags for other transforms. Windows 9x doesn't support HDC transforms outside of + //// translation (rotation for example), and this likely impacted the decision to only have a translation + //// flag when this was originally written. Debug.Assert(apply.HasFlag(ApplyGraphicsProperties.Clipping) || graphics.Clip is null || graphics.Clip.GetHrgn(graphics) == IntPtr.Zero, "Must preserve Graphics clipping region!"); - Debug.Assert(apply.HasFlag(ApplyGraphicsProperties.TranslateTransform) - || graphics.Transform is null - || graphics.Transform.IsIdentity, - "Must preserve Graphics transformation!"); + // TODO: We need to address this, since the Assert crashes VS at runtime when we're exploring a debug build. + // Debug.Assert(apply.HasFlag(ApplyGraphicsProperties.TranslateTransform) + // || graphics.Transform is null + // || graphics.Transform.IsIdentity, + // "Must preserve Graphics transformation!"); } #endif diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Theming/DarkThemedSystemColors.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Theming/DarkThemedSystemColors.cs new file mode 100644 index 00000000000..98c49e7e270 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Theming/DarkThemedSystemColors.cs @@ -0,0 +1,49 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Drawing; + +namespace System.Windows.Forms +{ + internal class DarkThemedSystemColors : ThemedSystemColors + { + private static DarkThemedSystemColors? s_instance; + + public static DarkThemedSystemColors DefaultInstance => s_instance ??= new DarkThemedSystemColors(); + + public override Color ActiveBorder => Color.FromArgb(255, 70, 70, 70); + public override Color ActiveCaption => Color.FromArgb(255, 60, 95, 120); + public override Color ActiveCaptionText => Color.FromArgb(255, 190, 190, 190); + public override Color AppWorkspace => Color.FromArgb(255, 60, 60, 60); + public override Color ButtonFace => Color.FromArgb(255, 55, 55, 55); + public override Color ButtonHighlight => Color.FromArgb(255, 105, 105, 105); + public override Color ButtonShadow => Color.FromArgb(255, 70, 70, 70); + public override Color Control => Color.FromArgb(255, 32, 32, 32); + public override Color ControlDark => Color.FromArgb(255, 70, 70, 70); + public override Color ControlDarkDark => Color.FromArgb(255, 45, 45, 45); + public override Color ControlLight => Color.FromArgb(255, 75, 75, 75); + public override Color ControlLightLight => Color.FromArgb(255, 95, 95, 95); + public override Color ControlText => Color.FromArgb(255, 190, 190, 190); + public override Color Desktop => Color.FromArgb(255, 30, 30, 30); + public override Color GradientActiveCaption => Color.FromArgb(255, 65, 100, 130); + public override Color GradientInactiveCaption => Color.FromArgb(255, 85, 115, 150); + public override Color GrayText => Color.FromArgb(255, 140, 140, 140); + public override Color Highlight => Color.FromArgb(255, 40, 100, 180); + public override Color HighlightText => Color.FromArgb(255, 255, 255, 255); + public override Color HotTrack => Color.FromArgb(255, 45, 95, 175); + public override Color InactiveBorder => Color.FromArgb(255, 60, 63, 65); + public override Color InactiveCaption => Color.FromArgb(255, 55, 75, 90); + public override Color InactiveCaptionText => Color.FromArgb(255, 190, 190, 190); + public override Color Info => Color.FromArgb(255, 80, 80, 60); + public override Color InfoText => Color.FromArgb(255, 190, 190, 190); + public override Color Menu => Color.FromArgb(255, 55, 55, 55); + public override Color MenuBar => Color.FromArgb(255, 55, 55, 55); + public override Color MenuHighlight => Color.FromArgb(255, 42, 128, 210); + public override Color MenuText => Color.FromArgb(255, 240, 240, 240); + public override Color ScrollBar => Color.FromArgb(255, 80, 80, 80); + public override Color Window => Color.FromArgb(255, 30, 30, 30); + public override Color WindowFrame => Color.FromArgb(255, 40, 40, 40); + public override Color WindowText => Color.FromArgb(255, 240, 240, 240); + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Theming/ForcedLightThemedSystemColors.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Theming/ForcedLightThemedSystemColors.cs new file mode 100644 index 00000000000..632c7fbb19b --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Theming/ForcedLightThemedSystemColors.cs @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Drawing; + +namespace System.Windows.Forms +{ + /// + /// This is a temporary list of the light color palette that is used when the system is in "normal light mode". + /// It's purely for testing purposes and will most likely be removed once the system colors are available. + /// + internal class ForcedLightThemedSystemColors : ThemedSystemColors + { + private static ForcedLightThemedSystemColors? s_instance; + + public static ForcedLightThemedSystemColors DefaultInstance => s_instance ??= new ForcedLightThemedSystemColors(); + + public override Color ActiveBorder => Color.FromArgb(255, 180, 180, 180); + public override Color ActiveCaption => Color.FromArgb(255, 153, 180, 209); + public override Color ActiveCaptionText => Color.FromArgb(255, 0, 0, 0); + public override Color AppWorkspace => Color.FromArgb(255, 171, 171, 171); + public override Color ButtonFace => Color.FromArgb(255, 240, 240, 240); + public override Color ButtonHighlight => Color.FromArgb(255, 255, 255, 255); + public override Color ButtonShadow => Color.FromArgb(255, 160, 160, 160); + public override Color Control => Color.FromArgb(255, 240, 240, 240); + public override Color ControlDark => Color.FromArgb(255, 160, 160, 160); + public override Color ControlDarkDark => Color.FromArgb(255, 105, 105, 105); + public override Color ControlLight => Color.FromArgb(255, 227, 227, 227); + public override Color ControlLightLight => Color.FromArgb(255, 255, 255, 255); + public override Color ControlText => Color.FromArgb(255, 0, 0, 0); + public override Color Desktop => Color.FromArgb(255, 0, 0, 0); + public override Color GradientActiveCaption => Color.FromArgb(255, 185, 209, 234); + public override Color GradientInactiveCaption => Color.FromArgb(255, 215, 228, 242); + public override Color GrayText => Color.FromArgb(255, 109, 109, 109); + public override Color Highlight => Color.FromArgb(255, 0, 120, 215); + public override Color HighlightText => Color.FromArgb(255, 255, 255, 255); + public override Color HotTrack => Color.FromArgb(255, 0, 102, 204); + public override Color InactiveBorder => Color.FromArgb(255, 244, 247, 252); + public override Color InactiveCaption => Color.FromArgb(255, 191, 205, 219); + public override Color InactiveCaptionText => Color.FromArgb(255, 0, 0, 0); + public override Color Info => Color.FromArgb(255, 255, 255, 225); + public override Color InfoText => Color.FromArgb(255, 0, 0, 0); + public override Color Menu => Color.FromArgb(255, 240, 240, 240); + public override Color MenuBar => Color.FromArgb(255, 240, 240, 240); + public override Color MenuHighlight => Color.FromArgb(255, 51, 153, 255); + public override Color MenuText => Color.FromArgb(255, 0, 0, 0); + public override Color ScrollBar => Color.FromArgb(255, 200, 200, 200); + public override Color Window => Color.FromArgb(255, 255, 255, 255); + public override Color WindowFrame => Color.FromArgb(255, 100, 100, 100); + public override Color WindowText => Color.FromArgb(255, 0, 0, 0); + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Theming/LightThemedSystemColors.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Theming/LightThemedSystemColors.cs new file mode 100644 index 00000000000..1b228c7a678 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Theming/LightThemedSystemColors.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Windows.Forms +{ + internal class LightThemedSystemColors : ThemedSystemColors + { + private static LightThemedSystemColors? s_instance; + + public static LightThemedSystemColors DefaultInstance => s_instance ??= new LightThemedSystemColors(); + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Theming/ThemedSystemColors.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Theming/ThemedSystemColors.cs new file mode 100644 index 00000000000..60bd0ea6890 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Theming/ThemedSystemColors.cs @@ -0,0 +1,178 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Drawing; + +namespace System.Windows.Forms; + +/// +/// Represents a class that provides themed system colors. +/// +public abstract class ThemedSystemColors +{ + /// + /// Gets the active border color. + /// + public virtual Color ActiveBorder { get; } = SystemColors.ActiveBorder; + + /// + /// Gets the window color. + /// + public virtual Color Window { get; } = SystemColors.Window; + + /// + /// Gets the scroll bar color. + /// + public virtual Color ScrollBar { get; } = SystemColors.ScrollBar; + + /// + /// Gets the menu text color. + /// + public virtual Color MenuText { get; } = SystemColors.MenuText; + + /// + /// Gets the menu highlight color. + /// + public virtual Color MenuHighlight { get; } = SystemColors.MenuHighlight; + + /// + /// Gets the menu bar color. + /// + public virtual Color MenuBar { get; } = SystemColors.MenuBar; + + /// + /// Gets the menu color. + /// + public virtual Color Menu { get; } = SystemColors.Menu; + + /// + /// Gets the info text color. + /// + public virtual Color InfoText { get; } = SystemColors.InfoText; + + /// + /// Gets the info color. + /// + public virtual Color Info { get; } = SystemColors.Info; + + /// + /// Gets the inactive caption text color. + /// + public virtual Color InactiveCaptionText { get; } = SystemColors.InactiveCaptionText; + + /// + /// Gets the inactive caption color. + /// + public virtual Color InactiveCaption { get; } = SystemColors.InactiveCaption; + + /// + /// Gets the inactive border color. + /// + public virtual Color InactiveBorder { get; } = SystemColors.InactiveBorder; + + /// + /// Gets the hot track color. + /// + public virtual Color HotTrack { get; } = SystemColors.HotTrack; + + /// + /// Gets the highlight text color. + /// + public virtual Color HighlightText { get; } = SystemColors.HighlightText; + + /// + /// Gets the highlight color. + /// + public virtual Color Highlight { get; } = SystemColors.Highlight; + + /// + /// Gets the window frame color. + /// + public virtual Color WindowFrame { get; } = SystemColors.WindowFrame; + + /// + /// Gets the gray text color. + /// + public virtual Color GrayText { get; } = SystemColors.GrayText; + + /// + /// Gets the gradient active caption color. + /// + public virtual Color GradientActiveCaption { get; } = SystemColors.GradientActiveCaption; + + /// + /// Gets the desktop color. + /// + public virtual Color Desktop { get; } = SystemColors.Desktop; + + /// + /// Gets the control text color. + /// + public virtual Color ControlText { get; } = SystemColors.ControlText; + + /// + /// Gets the control light light color. + /// + public virtual Color ControlLightLight { get; } = SystemColors.ControlLightLight; + + /// + /// Gets the control light color. + /// + public virtual Color ControlLight { get; } = SystemColors.ControlLight; + + /// + /// Gets the control dark dark color. + /// + public virtual Color ControlDarkDark { get; } = SystemColors.ControlDarkDark; + + /// + /// Gets the control dark color. + /// + public virtual Color ControlDark { get; } = SystemColors.ControlDark; + + /// + /// Gets the control color. + /// + public virtual Color Control { get; } = SystemColors.Control; + + /// + /// Gets the button shadow color. + /// + public virtual Color ButtonShadow { get; } = SystemColors.ButtonShadow; + + /// + /// Gets the button highlight color. + /// + public virtual Color ButtonHighlight { get; } = SystemColors.ButtonHighlight; + + /// + /// Gets the button face color. + /// + public virtual Color ButtonFace { get; } = SystemColors.ButtonFace; + + /// + /// Gets the application workspace color. + /// + public virtual Color AppWorkspace { get; } = SystemColors.AppWorkspace; + + /// + /// Gets the active caption text color. + /// + public virtual Color ActiveCaptionText { get; } = SystemColors.ActiveCaptionText; + + /// + /// Gets the active caption color. + /// + public virtual Color ActiveCaption { get; } = SystemColors.ActiveCaption; + + /// + /// Gets the gradient inactive caption color. + /// + public virtual Color GradientInactiveCaption { get; } = SystemColors.GradientActiveCaption; + + /// + /// Gets the window text color. + /// + public virtual Color WindowText { get; } = SystemColors.WindowText; +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ToolTip/DrawToolTipEventArgs.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ToolTip/DrawToolTipEventArgs.cs index c60441201b7..e0d3f1ebd2f 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/ToolTip/DrawToolTipEventArgs.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ToolTip/DrawToolTipEventArgs.cs @@ -98,6 +98,6 @@ public void DrawText(TextFormatFlags flags) /// public void DrawBorder() { - ControlPaint.DrawBorder(Graphics, Bounds, SystemColors.WindowFrame, ButtonBorderStyle.Solid); + ControlPaint.DrawBorder(Graphics, Bounds, Application.SystemColors.WindowFrame, ButtonBorderStyle.Solid); } } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ToolTip/ToolTip.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ToolTip/ToolTip.cs index b35adb4c92a..c1c0d593f53 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/ToolTip/ToolTip.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ToolTip/ToolTip.cs @@ -40,8 +40,8 @@ public partial class ToolTip : Component, IExtenderProvider, IHandle private ToolTipNativeWindow _window; private Control? _topLevelControl; private bool _active = true; - private Color _backColor = SystemColors.Info; - private Color _foreColor = SystemColors.InfoText; + private Color _backColor = Application.SystemColors.Info; + private Color _foreColor = Application.SystemColors.InfoText; private bool _isBalloon; private bool _isDisposing; private string _toolTipTitle = string.Empty; @@ -770,12 +770,12 @@ private unsafe void CreateHandle() // Set active status. PInvoke.SendMessage(this, PInvoke.TTM_ACTIVATE, (WPARAM)(BOOL)_active); - if (BackColor != SystemColors.Info) + if (BackColor != Application.SystemColors.Info) { PInvoke.SendMessage(this, PInvoke.TTM_SETTIPBKCOLOR, (WPARAM)BackColor); } - if (ForeColor != SystemColors.InfoText) + if (ForeColor != Application.SystemColors.InfoText) { PInvoke.SendMessage(this, PInvoke.TTM_SETTIPTEXTCOLOR, (WPARAM)ForeColor); } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/VisualStyles/VisualStyleInformation.cs b/src/System.Windows.Forms/src/System/Windows/Forms/VisualStyles/VisualStyleInformation.cs index 47e5a4353d8..92f45826228 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/VisualStyles/VisualStyleInformation.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/VisualStyles/VisualStyleInformation.cs @@ -180,14 +180,14 @@ public static int MinimumColorDepth /// public static Color TextControlBorder => Application.RenderWithVisualStyles ? SetParameters(VisualStyleElement.TextBox.TextEdit.Normal).GetColor(ColorProperty.BorderColor) - : SystemColors.WindowFrame; + : Application.SystemColors.WindowFrame; /// /// This is the color buttons and tab pages are highlighted with when they are moused over on themed OS. /// public static Color ControlHighlightHot => Application.RenderWithVisualStyles ? SetParameters(VisualStyleElement.Button.PushButton.Normal).GetColor(ColorProperty.AccentColorHint) - : SystemColors.ButtonHighlight; + : Application.SystemColors.ButtonHighlight; private static VisualStyleRenderer SetParameters(VisualStyleElement element) { diff --git a/src/System.Windows.Forms/tests/IntegrationTests/UIIntegrationTests/Infra/ControlTestBase.cs b/src/System.Windows.Forms/tests/IntegrationTests/UIIntegrationTests/Infra/ControlTestBase.cs index c88825b4662..63c076510de 100644 --- a/src/System.Windows.Forms/tests/IntegrationTests/UIIntegrationTests/Infra/ControlTestBase.cs +++ b/src/System.Windows.Forms/tests/IntegrationTests/UIIntegrationTests/Infra/ControlTestBase.cs @@ -334,7 +334,9 @@ protected async Task RunFormAsync(Func<(Form dialog, T control)> createDialog Assert.NotNull(control); dialog.Activated += (sender, e) => gate.TrySetResult(default); +#pragma warning disable VSTHRD103 // Call async methods when in an async method dialog.ShowDialog(); +#pragma warning restore VSTHRD103 // Call async methods when in an async method await test.JoinAsync(); } @@ -375,7 +377,9 @@ protected async Task RunFormWithoutControlAsync(Func createForm, F Assert.NotNull(dialog); dialog.Activated += (sender, e) => gate.TrySetResult(default); +#pragma warning disable VSTHRD103 // Call async methods when in an async method dialog.ShowDialog(); +#pragma warning restore VSTHRD103 // Call async methods when in an async method await test.JoinAsync(); } diff --git a/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/StatusStripTests.cs b/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/StatusStripTests.cs index 375900906f9..50701b32b3d 100644 --- a/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/StatusStripTests.cs +++ b/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/StatusStripTests.cs @@ -121,8 +121,11 @@ public void StatusStrip_Ctor_Default() Assert.Null(control.Region); Assert.NotNull(control.Renderer); Assert.Same(control.Renderer, control.Renderer); - Assert.IsType(control.Renderer); - Assert.Equal(ToolStripRenderMode.System, control.RenderMode); + + // TODO: Assume control.Renderer can be either ToolStripSystemRenderer or ToolStripProfessionalRenderer for the Moment. + Assert.True(control.Renderer is ToolStripSystemRenderer or ToolStripProfessionalRenderer, "Renderer is not one of the expected types."); + Assert.True(control.RenderMode is ToolStripRenderMode.System or ToolStripRenderMode.ManagerRenderMode); + Assert.True(control.ResizeRedraw); Assert.Equal(200, control.Right); Assert.Equal(RightToLeft.No, control.RightToLeft);