Replies: 93 comments 5 replies
-
Thanks! Project Reunion APIs will be defined in metadata like WinRT objects are so they can be projected to all languages and all runtimes. Can you mock up what an API for this would look like? Maybe something like: enum WindowThemePreferenceColorMode {
None = 0,
Dark,
Light
}
runtimeclass WindowThemePreference {
static WindowThemePreferenceColorMode SystemColorMode { get; };
static WindowThemePreferenceColorMode AppColorMode { get; };
static event EventHandler<Object> PreferenceChanged;
static void SetAppPreferredColorMode(WindowThemePreferenceColorMode mode);
static void SetWindowPreferredColorMode(WindowId window, WindowThemePreferenceColorMode mode);
static void SetWindowTitleBarPreferredColorMode(WindowId window, WindowThemePreferenceColorMode mode);
} |
Beta Was this translation helpful? Give feedback.
-
Ideally it would remain a RequestedTheme = Light/Dark value in the App.xaml or Window Xaml element. The Window Frame and TitleBar reflecting that setting, or if it is not set, the System setting. |
Beta Was this translation helpful? Give feedback.
-
My suggestion is for non-XAML code, so I can't adopt WinUI's UWP app model "clone" intended for desktop apps either without a significant rewrite. C++/WinRT is already causing compilation time and error headaches even when only a small part of my code is using it, so I would actually rather not adopt it at all (not to mention that IDL is a complete PITA). If a WinRT API for this only supports WinUI desktop app scenarios, it would be useless to me, and I'll just use the undocumented functions I listed above. I would suggest documenting the OS APIs that I listed (and already exist as well as being usable in For example, a Delphi-based Win32 app (you know those still exist) or a C++ app using an older version of the C++ compiler (like VS2013) could use This might not be in the scope of Project Reunion itself, but it's where I was told to file feedback about it. |
Beta Was this translation helpful? Give feedback.
-
If this isn't the place to request raw Win32 APIs, feel free to redirect me to the right place (except if that place is the Feedback Hub, my confidence in it has been reduced to 0) |
Beta Was this translation helpful? Give feedback.
-
Project Reunion is about making APIs available to all apps - no matter which language, UX framework, runtime, or packaging system you use. WinUI-specific APIs would go in the WinUI repo. We're still planning out which language projections to add - issue #18 has a proposed projection of an IDL based type for "flat C." Can you add comments / bumps to it so we can get a sense of which projections are important? See also issues tagged with "projection" for others folks have asked for. Some Project Reunion APIs will also be "flat C to start" (ie: direct exports from the DLL with an associated header & import library) and then also get a metadata wrapper for languages & runtimes whose FFI is cumbersome. Can you also file an issue in the cppwinrt repo for compilation times? (@kennykerr) |
Beta Was this translation helpful? Give feedback.
-
Of course, I'm not opposed to providing a WinRT projection as well, I just believe that stabilizing the Win32 APIs would be best, as there are already existing users of those in the wild, and providing a guarantee the API won't break or be removed from under their feet would be best. It's also much simpler for those who can't use existing projections to use those. Documenting and then wrapping those APIs in a WinRT class would also take less time than reimplementing them in WinRT. |
Beta Was this translation helpful? Give feedback.
-
As for the compilation times, it's more of an inherent issue with C++ compilers, should be somewhat fixed when modules support is enabled in C++/WinRT. |
Beta Was this translation helpful? Give feedback.
-
Aha! Check out the UISettings type from your Win32 apps, like this (C++/WinRT) example: winrt::Windows::UI::ViewManagement::UISettings settings;
auto fg = settings.GetColorValue(winrt::Windows::UI::ViewManagement::UIColorType::Foreground);
auto bg = settings.GetColorValue(winrt::Windows::UI::ViewManagement::UIColorType::Background); Apps can listen to changes to this setting on the UISettings.ColorValuesChanged event. There's also the (missing a verb) UIElementColor method, which you can for specific colors of UX components. While you can't ask "are you dark/light/custom mode", you can definitely get the set of colors used by Windows to theme its own UX elements, which would let your apps be consistent. |
Beta Was this translation helpful? Give feedback.
-
That certainly can work if you do your own custom drawing, but it doesn't cover cases where your UI kit has a simple dark/light toggle, where you have to guesstimate if bg is dark or light, neither does it cover the case where your app uses common controls or context menus with no custom drawing. For example, XAML islands supports dark/light theming according to user preferences, but it doesn't update the theme when the user changes it in settings, so when my app receives Also, if your app has a tray icon, you may want to know if the system uses a light or dark theme (not the apps), to choose the appropriate tray icon color (a white tray icon for the dark theme, and a black tray icon for the light theme) |
Beta Was this translation helpful? Give feedback.
-
I'm getting ready to support Windows 11 in a Win32 app, and the Windows 11 developer documentation encourages developers to "Support Dark and Light themes." My app's styling needs are very minimal - just the title bar - but it seems I will still need to resort to undocumented APIs. I hope this can be resolved soon. |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
It's not undocumented, I found it in the latest insider preview SDK (build 22000). |
Beta Was this translation helpful? Give feedback.
-
@zodiacon yes, for information bellow this is the enum DWMWINDOWATTRIBUTE
{
DWMWA_NCRENDERING_ENABLED = 1, // [get] Is non-client rendering enabled/disabled
DWMWA_NCRENDERING_POLICY, // [set] DWMNCRENDERINGPOLICY - Non-client rendering policy
DWMWA_TRANSITIONS_FORCEDISABLED, // [set] Potentially enable/forcibly disable transitions
DWMWA_ALLOW_NCPAINT, // [set] Allow contents rendered in the non-client area to be visible on the DWM-drawn frame.
DWMWA_CAPTION_BUTTON_BOUNDS, // [get] Bounds of the caption button area in window-relative space.
DWMWA_NONCLIENT_RTL_LAYOUT, // [set] Is non-client content RTL mirrored
DWMWA_FORCE_ICONIC_REPRESENTATION, // [set] Force this window to display iconic thumbnails.
DWMWA_FLIP3D_POLICY, // [set] Designates how Flip3D will treat the window.
DWMWA_EXTENDED_FRAME_BOUNDS, // [get] Gets the extended frame bounds rectangle in screen space
DWMWA_HAS_ICONIC_BITMAP, // [set] Indicates an available bitmap when there is no better thumbnail representation.
DWMWA_DISALLOW_PEEK, // [set] Don't invoke Peek on the window.
DWMWA_EXCLUDED_FROM_PEEK, // [set] LivePreview exclusion information
DWMWA_CLOAK, // [set] Cloak or uncloak the window
DWMWA_CLOAKED, // [get] Gets the cloaked state of the window
DWMWA_FREEZE_REPRESENTATION, // [set] BOOL, Force this window to freeze the thumbnail without live update
DWMWA_PASSIVE_UPDATE_MODE, // [set] BOOL, Updates the window only when desktop composition runs for other reasons
+ DWMWA_USE_HOSTBACKDROPBRUSH, // [set] BOOL, Allows the use of host backdrop brushes for the window.
+ DWMWA_USE_IMMERSIVE_DARK_MODE = 20, // [set] BOOL, Allows a window to either use the accent color, or dark, according to the user Color Mode preferences.
+ DWMWA_WINDOW_CORNER_PREFERENCE = 33, // [set] WINDOW_CORNER_PREFERENCE, Controls the policy that rounds top-level window corners
+ DWMWA_BORDER_COLOR, // [set] COLORREF, The color of the thin border around a top-level window
+ DWMWA_CAPTION_COLOR, // [set] COLORREF, The color of the caption
+ DWMWA_TEXT_COLOR, // [set] COLORREF, The color of the caption text
+ DWMWA_VISIBLE_FRAME_BORDER_THICKNESS, // [get] UINT, width of the visible border around a thick frame window
DWMWA_LAST
}; So the |
Beta Was this translation helpful? Give feedback.
-
I am still hopeful :) |
Beta Was this translation helpful? Give feedback.
-
Please hold off on using these undocumented APIs/constants. There will be a supported path, stay tuned! |
Beta Was this translation helpful? Give feedback.
This comment has been minimized.
This comment has been minimized.
-
WinForms are looking to provide dark mode support, but that would require the dark mode common controls mentioned here. Otherwise it would be impossible unless WinForms owner draw all of its controls, which kind of defeats its purpose. |
Beta Was this translation helpful? Give feedback.
-
Some people have found it wrong too, though some also found it correct: ysc3839/win32-darkmode#3. I'm not sure what's the reason. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
This issue will probably go nowhere, because while it seemed like the initial goal of Project Reunion could've helped this, it now seems apparent that WASDK is just support for WinUI 3, and has little interest for any classic Win32 app. |
Beta Was this translation helpful? Give feedback.
-
Microsoft claims they'll have documentation on developing modern, fast, and reliable Windows apps available by BUILD timeframe https://twitter.com/WindowsDocs/status/1767636607195385951. Something to keep an eye on, but don't hold your breath. |
Beta Was this translation helpful? Give feedback.
-
Hell, PowerToys and Accessibility Insights are now also reading the registry to detect dark mode, because the platform cannot give us a satisfying API for this: https://github.com/microsoft/PowerToys/blob/f5797a065a5c2c448fd2b1780bd1353d712103c3/src/common/Themes/theme_helpers.cpp#L17-L24 And WPF soon will too: I guess reading registry will be a supported way going forward if that's any indication 🙄 |
Beta Was this translation helpful? Give feedback.
-
So will WinForms too, apparently: dotnet/winforms#7641 (comment) Very disappointing that a proper API has not been added for this. |
Beta Was this translation helpful? Give feedback.
-
Just realized, WPF will also fallback to I suppose this means |
Beta Was this translation helpful? Give feedback.
-
Sometimes the apis are bugged so registry is sadly the best way. |
Beta Was this translation helpful? Give feedback.
-
Someone told me in this thread that the registry key may not be present : |
Beta Was this translation helpful? Give feedback.
-
Yes, can confirm the above. On a clean 1809 install (which I made to test this particular thing), the only keys under |
Beta Was this translation helpful? Give feedback.
-
No, these keys are undocumented. And the defaults have varied depending on the OS version. This is why it's important we have a proper API |
Beta Was this translation helpful? Give feedback.
-
If I follow the thread correctly, the uxtheme APIs are still undocumented and there is also no WinRT-exposed call I could use to get the effect of the undocumented Similarly, I don't have a way to set the light/dark mode of the common open/save dialog I show. Instead, it always shows with the system setting. I also use |
Beta Was this translation helpful? Give feedback.
-
@RDMacLachlan why did this get converted to a discussion? The problem initially raised did not get solved. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Discussion: Dark mode for applications
Currently, reliably detecting dark mode in Win32 applications requires either reading the registry or using undocumented methods from
uxtheme.dll
.I strongly suggest to document those two existing methods:
ShouldAppsUseDarkMode
:WM_SETTINGCHANGE
.ShouldSystemUseDarkMode
:WM_SETTINGCHANGE
.This will allow existing apps to easily implement dark theme support, and to follow system settings without relying on workarounds. A WinRT API should probably be exposed (the two settings and an event to listen for changes) as well, but some applications are already tentatively using those two APIs, so it would be the best case to document the Win32 APIs, as those won't have to do any significant work to adopt an official solution rather than an undocumented one (and, truth be told, they are much simpler to use than their WinRT counterparts, especially if your language doesn't have a WinRT projection available)
Also, there exists other APIs in
uxtheme.dll
which might be of interest for people transitioning to WinUI and/or XAML islands:SetPreferredAppMode
:AllowDarkModeForWindow
:AllowDark
using the API above, it is a per-window opt-in.DarkMode_Explorer
for this to be effectiveUI_PKEY_DarkModeRibbon
Those methods are useful because when transitioning, it allows developers to use a dark theme for old controls and new controls alike, to get a somewhat consistent UI. Darkening Win32 or winforms controls manually is extremely hard to get right, and leveraging the work done in Windows Explorer would prevent a lot of misdirected attempts at dark theming Win32 controls.
EVEN MORE, there's an undocumented window attribute allowing dark mode title bars (
DWMWA_USE_IMMERSIVE_DARK_MODE
). This one was even used by the command prompt itself and openly on GitHub, before it got removed from the OSS version because it was internal (see microsoft/terminal@bc7eb96#diff-e26a93b2aa9fea92ebf24336c4fe6412L19-L22). No true dark mode comes without a dark titlebar, and customizing the titlebar is a complex endeavour that would be greatly simplified by the publication of this attribute.All of the APIs mentioned have been added since the introduction of dark mode Explorer, and have proven to be stable or only very slightly modified, so I'm sad they are being kept private because it would allow so many apps to get a dark mode (light mode makes me cry 😢)
Beta Was this translation helpful? Give feedback.
All reactions