Search code examples
winapiwindows-10windows-themes

Notification/subscription method for Windows 10 theme change


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.


Solution

  • 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
            }
        }