Handle Dark/Light change of Windows?
How can I handle Dark/Light change of Windows for displayed window? After changing the Dark/Light setting for apps in Windows settings, opening a new window follows the new theme, but the old main window is still in old theme.
To me, this seems too complicated to implement and there is IMHO not much demand and use for such a feature...
It would require to keep a list of weak references to all the controls and then loop through it, setting the colors and perhaps handling potential "special needs" of some of them.
While I recently added a static ConditionalWeakTable to track already processed controls, this cannot be directly used as it does not expose its Keys and Values collections.
And adding support for switching back to the light theme would add one more level of complexity
Hi, all windows get themed when they are created and if Windows theme changes when your program is still running you will have to find a way to re-launch your main window for the colors to be applied.
Now that you have code to force a theme can you please add an option to handle theme change? I tried to override WndProc and handle WM_THEMECHANGED but the code is never executed. Is changing dark/light mode raising a different message?
ok, the message is called WM_SETTINGSCHANGE and here you need to check the LParam var stringLParam = Marshal.PtrToStringAuto(m.LParam); if this is set to ImmersiveColorSet (if (stringLParam == "ImmersiveColorSet")) the theme changed via settings app.
Here you also need to update your public bool IsDarkMode as it is currently only assigned at constructor and return wrong values after dark /light change.
Best would be to have an enum with FollowSystemTheme (handle the WM_SETTINGSCHANGE message and change colors), ForceLightTheme, ForceDarkTheme to force a color no matter what is set in windows.
ok, I had to create a new base Form class and later inherit my forms from this base form class. In the base form class I added the overriding of WndProc and a protected variable protected DarkModeCS dm; which I assign in each constructor base.dm = new DarkModeCS(this); and depending on the return of GetWindowsColorMode() I call dm.ApplyTheme(true); or dm.ApplyTheme(false); and also update the IsDarkMode property.
This works fine so far and the window get redrawn in the now correct colors.
@MagicAndre1981 ..an option to handle theme change.. What do you mean by that? an event?
Ohh yes, i forgot to update the IsDarkMode prop, thanks for the remind.
This was one of the things that my Pull Request addressed. In the form you needed to reapply the theme to you could simply call the reference to a DarkModeCS instance and run the ApplyTheme() method. This would refetch the IsDarkMode property and reapply the theme. Sorry I didn't elaborate more on what I was using the Pull Request code for at the time.
Ref: https://github.com/BlueMystical/Dark-Mode-Forms/pull/40
@BlueMystical I've added a PR for this in #59 Hopefully I haven't missed anything.
Thank you!
ok, update the doc, to include the changes and add the hint to inherit from the new base class.