5

As yolu may have noticed, MS introduced a modern kind of 'theming' in Windows 10 regarding the basic OS elements like start menu and taskbar. With newer versions, you can choose a 'light' theme as an alternative to the default black theme.

I was wondering if there is an API or hook to elegantly and (more importantly) efficiently check live for theme changes (Did not find anything in the MS docs regarding this, but often enough these gems are pretty hidden there IMHO).

Specific problem: When you have a desktop application with a system tray icon, chances are high that you designed it to be bright. Nearly all of the modern Windows icons feature such a style (simple and white, yielding good readability on the black taskbar). Now you can provide a different version in a darker style for the light theme, but how to notice when to apply this on the fly?

I'm aware of the registry key under HCU (Software/Microsoft/Windows/CurrentVersion/Themes/Personalize) which is what I'm utilizing right now. However, blindly checking for change every x milliseconds seems pretty awkward.

If no such thing is available, I'm also happy to hear some ideas for more efficient implementations of such a check.

dfuchs
  • 360
  • 2
  • 8
  • Related: [How to detect Windows 10 light/dark mode in Win32 application?](https://stackoverflow.com/q/51334674/7571258) – zett42 Sep 02 '19 at 11:27
  • WinRT class `UISettings` exposes the [`ColorValuesChanged`](https://learn.microsoft.com/en-us/uwp/api/windows.ui.viewmanagement.uisettings.colorvalueschanged) event. Starting from [this answer](https://stackoverflow.com/a/55670413/7571258), I was able to quickly hack together a C++/WinRT console app that subscribes to that event. I leave it to make that an actual answer to people who are more knowledgable in C++/WinRT. – zett42 Sep 02 '19 at 12:02
  • Possible duplicate of [How to detect Windows 10 light/dark mode in Win32 application?](https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application) – Christian.K Sep 03 '19 at 05:19
  • @Christian.K Not really IMHO, albeit there are some overlappings. It has to be distinguished between the app theme (UWP framework/APIs) and the system theme - I‘ll go for the hint from Strive Sun ATM – dfuchs Sep 03 '19 at 07:10

1 Answers1

6

Method 1: Use RegNotifyChangeKeyValue

Notifies the caller about changes to the attributes or contents of a specified registry key.

Methon 2: Use WM_SETTINGCHANGE

Applications should send WM_SETTINGCHANGE to all top-level windows when they make changes to system parameters. (This message cannot be sent directly to a window.) To send the WM_SETTINGCHANGE message to all top-level windows, use the SendMessageTimeout function with the hwnd parameter set to HWND_BROADCAST.

I tend to use the second method, I have tried, and have been able to work successfully.

Minimum code example:

case WM_SETTINGCHANGE:
    {
        if (!lstrcmp(LPCTSTR(lParam), L"ImmersiveColorSet"))
        {
            //theme has been changed
        }
    }
Strive Sun
  • 5,988
  • 1
  • 9
  • 26