Skip to content

Commit 68404dd

Browse files
Refactor some darkmode checks.
1 parent 76b0b7b commit 68404dd

File tree

2 files changed

+50
-22
lines changed

2 files changed

+50
-22
lines changed

src/System.Windows.Forms/src/System/Windows/Forms/Application.cs

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public sealed partial class Application
5050

5151
private const string DarkModeKeyPath = "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
5252
private const string DarkModeKey = "AppsUseLightTheme";
53-
private const int DarkModeNotAvailable = -1;
53+
private const int SystemDarkModeDisabled = -1;
5454

5555
/// <summary>
5656
/// Events the user can hook into
@@ -277,7 +277,14 @@ public static void SetColorMode(SystemColorMode systemColorMode)
277277
return;
278278
}
279279

280-
if (GetSystemColorModeInternal() > -1)
280+
if ((systemColorMode == SystemColorMode.Dark && IsSystemDarkModeAvailable)
281+
|| systemColorMode == SystemColorMode.Classic)
282+
{
283+
s_systemColorMode = systemColorMode;
284+
return;
285+
}
286+
287+
if (GetSystemColorModeInternal() > SystemDarkModeDisabled)
281288
{
282289
s_systemColorMode = systemColorMode;
283290
return;
@@ -348,43 +355,41 @@ static void NotifySystemEventsOfColorChange()
348355
? SystemColorMode.Dark
349356
: SystemColorMode.Classic;
350357

351-
// Returns 0 if dark mode is available, otherwise -1 (DarkModeNotAvailable)
358+
// Returns 0 if dark mode is enabled in the system, otherwise -1 (SystemDarkModeDisabled)
352359
private static int GetSystemColorModeInternal()
353360
{
354-
if (SystemInformation.HighContrast)
361+
if (!IsSystemDarkModeAvailable)
355362
{
356-
return DarkModeNotAvailable;
363+
return SystemDarkModeDisabled;
357364
}
358365

359-
int systemColorMode = DarkModeNotAvailable;
366+
int systemColorMode = SystemDarkModeDisabled;
360367

361-
// Dark mode is supported when we are >= W11/22000
362-
// Technically, we could go earlier, but then the APIs we're using weren't officially public.
363-
if (OsVersion.IsWindows11_OrGreater())
368+
try
369+
{
370+
systemColorMode = (Registry.GetValue(
371+
keyName: DarkModeKeyPath,
372+
valueName: DarkModeKey,
373+
defaultValue: SystemDarkModeDisabled) as int?) ?? systemColorMode;
374+
}
375+
catch (Exception ex) when (!ex.IsCriticalException())
364376
{
365-
try
366-
{
367-
systemColorMode = (Registry.GetValue(
368-
keyName: DarkModeKeyPath,
369-
valueName: DarkModeKey,
370-
defaultValue: DarkModeNotAvailable) as int?) ?? systemColorMode;
371-
}
372-
catch (Exception ex) when (!ex.IsCriticalException())
373-
{
374-
}
375377
}
376378

377379
return systemColorMode;
378380
}
379381

382+
private static bool IsSystemDarkModeAvailable =>
383+
!SystemInformation.HighContrast && OsVersion.IsWindows11_OrGreater();
384+
380385
/// <summary>
381386
/// Gets a value indicating whether the application is running in a dark system color context.
382387
/// Note: In a high contrast mode, this will always return <see langword="false"/>.
383388
/// </summary>
384389
[Experimental(DiagnosticIDs.ExperimentalDarkMode, UrlFormat = DiagnosticIDs.UrlFormat)]
385390
public static bool IsDarkModeEnabled =>
386391
!SystemInformation.HighContrast
387-
&& (SystemColorMode == SystemColorMode.Dark);
392+
&& (ColorMode == SystemColorMode.Dark);
388393

389394
/// <summary>
390395
/// Gets the path for the executable file that started the application.

src/System.Windows.Forms/src/System/Windows/Forms/Form.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4309,6 +4309,29 @@ protected override void OnHandleCreated(EventArgs e)
43094309
{
43104310
_formStateEx[s_formStateExUseMdiChildProc] = (IsMdiChild && Visible) ? 1 : 0;
43114311
base.OnHandleCreated(e);
4312+
4313+
if (Properties.TryGetValue(s_propFormBorderColor, out Color? formBorderColor))
4314+
{
4315+
SetFormAttributeColorInternal(DWMWINDOWATTRIBUTE.DWMWA_BORDER_COLOR, formBorderColor.Value);
4316+
}
4317+
4318+
if (Properties.TryGetValue(s_propFormCaptionBackColor, out Color? formCaptionBackColor))
4319+
{
4320+
SetFormAttributeColorInternal(DWMWINDOWATTRIBUTE.DWMWA_CAPTION_COLOR, formCaptionBackColor.Value);
4321+
}
4322+
4323+
if (Properties.TryGetValue(s_propFormCaptionTextColor, out Color? formCaptionTextColor))
4324+
{
4325+
SetFormAttributeColorInternal(DWMWINDOWATTRIBUTE.DWMWA_TEXT_COLOR, formCaptionTextColor.Value);
4326+
}
4327+
4328+
#pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
4329+
if (Properties.TryGetValue(s_propFormCornerPreference, out FormCornerPreference? cornerPreference))
4330+
{
4331+
SetFormCornerPreferenceInternal(cornerPreference.Value);
4332+
}
4333+
#pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
4334+
43124335
UpdateLayered();
43134336
}
43144337

@@ -5912,7 +5935,7 @@ public DialogResult ShowDialog(IWin32Window? owner)
59125935
/// This method immediately returns, even if the form is large and takes a long time to be set up.
59135936
/// </para>
59145937
/// <para>
5915-
/// If the form is already displayed asynchronously by <see cref="Form.ShowAsync"/>, an <see cref="InvalidOperationException"/> will be thrown.
5938+
/// If the form is already displayed asynchronously by <see cref="ShowAsync"/>, an <see cref="InvalidOperationException"/> will be thrown.
59165939
/// </para>
59175940
/// <para>
59185941
/// An <see cref="InvalidOperationException"/> will also occur if no <see cref="WindowsFormsSynchronizationContext"/> could be retrieved or installed.
@@ -5947,7 +5970,7 @@ public DialogResult ShowDialog(IWin32Window? owner)
59475970
/// This method immediately returns, even if the form is large and takes a long time to be set up.
59485971
/// </para>
59495972
/// <para>
5950-
/// If the form is already displayed asynchronously by <see cref="Form.ShowAsync"/>, an <see cref="InvalidOperationException"/> will be thrown.
5973+
/// If the form is already displayed asynchronously by <see cref="ShowAsync"/>, an <see cref="InvalidOperationException"/> will be thrown.
59515974
/// </para>
59525975
/// <para>
59535976
/// An <see cref="InvalidOperationException"/> will also occur if no <see cref="WindowsFormsSynchronizationContext"/> could be retrieved or installed.

0 commit comments

Comments
 (0)