How do I programmatically obtain the user’s selected accent color in Windows 10?


If you want to obtain the user's accent color, you can ask the UISettings object for the current color value of UIColorType.Accent.

How you get this information depends on what kind of program you're writing.

If you're writing a Store app or a classic desktop program in C++/CX, then you do this:

namespace vm = Windows::UI::ViewManagement;

void GetAccentColor()
{
    auto settings = ref new vm::UISettings();
    auto color = settings->GetColorValue(vm::UIColorType::Accent);
    // color.A, color.R, color.G, and color.B are the color channels.
}

If you're writing a Store app or a classic desktop program in C#, then you do this:

using vm = Windows.UI.ViewManagement;

void GetAccentColor()
{
    var settings = new vm.UISettings();
    var color = settings.GetColorValue(vm.UIColorType.Accent);
    // color.A, color.R, color.G, and color.B are the color channels.
}

If you're writing a Store app in JavaScript, then you do this:

var vm = Windows.UI.ViewManagement;

function getAccentColor() {
    var settings = new vm.UISettings();
    var color = settings.getColorValue(vm.UIColorType.accent);
    // color.a, color.r, color.g, and color.b are the color channels.
}

If you're writing a Store app or a classic desktop program in raw C++ (you crazy person you), then you get to do this:

namespace abi_vm = ABI::Windows::UI::ViewManagement;
namespace wrl = Microsoft::WRL;
namespace wf = Windows::Foundation;

void GetAccentColor()
{
    // Error checking has been elided for expository purposes.
    wrl::ComPtr<abi_vm::IUISettings> settings;
    wf::ActivateInstance(wrl::Wrappers::HStringReference(
     RuntimeClass_Windows_UI_ViewManagement_UISettings).Get(), &settings);
    ABI::Windows::UI::Color color;
    settings->GetColorValue(abi_vm::UIColorType::Accent, &color);
    // color.A, color.R, color.G, and color.B are the color channels.
}

And if you're writing a Store app or a classic desktop program in C++/WinRT, you write this:

namespace winrt_vm = winrt::Windows::UI::ViewManagement;

void GetAccentColor()
{
    winrt_vm::UISettings settings;
    auto color = settings.GetColorValue(winrt_vm::UIColorType::Accent);
    // color.A, color.R, color.G, and color.B are the color channels.
}

Note that I used namespace aliases instead of importing the entire namespace. This makes the code a little bit uglier, but I think it's useful for expository purposes because it makes it clearer which namespace each identifier comes from.

Comments (20)
  1. SimonRev says:

    What, you weren’t masochistic enough to try and do it in C? Or perhaps VB6 would be a fun case too :)

    1. xcomcmdr says:

      I’d like to sse it in F#

      1. Pierre B. says:

        Why so easy?

        I want to see it in bash script, running in an emulator written is javascript in a internet brower, in Linux, under a VM running in Windows 10.

        With all the exploit code for each escape.

        As a one-liner that compiles to opcodes that maps to pure ASCII.

        (I suppose it only shows how much we hold Raymond’s ability to code in high esteem.)

    2. VB6 sounds too easy. I’d rather see it done in FORTRAN77 or COBOL.

  2. Now add error handling. WRL one doesn’t seem that bad afterwards in comparison.

    In my experience, while it is indeed easy to use C++/CX to write the code initially, it’s much harder to handle errors correctly, especially if you don’t use exceptions anywhere else in your codebase.

    1. WinRT is designed so that (for the most part) any exception means that you have a bug and crashing is appropriate. You can then study the crash dump to see what went wrong and fix it.

      1. That is provided you can reproduce the issue in-house. Sometimes you can’t. One of the harder issues with C++/CX to investigate that I can remember was us crashing on Clipboard::GetContent, which we called from our agile Clipboard::ContentChanged handler. That means we called GetContent on a threadpool thread. We called it without any exception handlers, and it seemed to work at first. Then we started receiving random complaints that the application was sometimes crashing. The callstack was something on the CoreWindow thread failing due to unhandled error. That’s all the information we had – Windows Store does not let you download and inspect crash dumps, so your suggestion would not have worked.

        Apparently, Clipboard::GetContent can return E_ACCESSDENIED if you happen to call it at exact moment a user alt-tabs away from the application. Without exception handlers, that gets turned into a C++/CX exception, which bubbles up to the top of event handler, and at that point it gets turned back into an HRESULT. Handler returns that failed HRESULT, and (I’m not sure exactly how this part works) the caller seems to send a message to the UI thread that something failed, which aborts the application. And at that point, it’s really hard to understand what happened, especially if you don’t have access to a crash dump.

        Had it been written using raw C++, it would have probably just ignored the failed HRESULT and returned success from the event handler regardless. We have not seen such hard to investigate bugs in newer code which was written without C++/CX – perhaps we’re just lucky – or perhaps C++/CX errors are indeed much harder to investigate.

        1. The crash dump should have a stowed exception that points back to the background thread, with a stack trace and HRESULT.

  3. skSdnW says:

    I don’t claim to know anything about WRL but I think you want IUISettings3 and not IUISettings?

  4. jon says:

    Since the plot to get people to abandon the desktop has failed miserably, is there any chance the API for “classic” apps could be made simpler in the future?

    (rhetorical question of course)

    1. xcomcmdr says:

      What’s that supposed to mean ?

    2. skSdnW says:

      In the current implementation GetColorValue calls a undocumented function in a normal desktop .DLL to get the color.

    3. MarcK4096 says:

      There’s an easy way to do it in C#. I’m happy.

  5. I was kinda hoping to do that in PowerShell.

    1. John ( other John ) says:

      Not a extension so users can call cmd.exe?

  6. John Elliott says:

    I can see we’ve really moved on from the days of GetSysColor(COLOR_ACTIVECAPTION);

  7. Azarien says:

    It’s getting annoying that interesting stuff like this is hard to access from desktop applications because WinRT (or whatever it is called now) is the “main” Windows API nowadays.
    My bet is that in 5 years from now, WinRT will be old, deprecated, replaced by something “better”, while good old desktop will still be around.

    1. GL says:

      WinRT is just another layer of COM. If COM was never popular for you in desktop apps, perhaps neither WinRT will be. I am surprised that it sounds, from Raymond’s blog, that many, if not most, developers are still using raw Win32 API.

      1. Lawrence says:

        Indeed, I would say the vast majority of developers for Windows are targeting Win32. Personally I don’t know anyone who develops for WinRT but I’m sure there are some out there.

        Win32 is still my preferred option too, for many reasons: 1) it doesn’t lock anyone out – remember there is a big userbase on Windows 7. 2) it’s mature, efficient, and proven. 3) “multiplatform” libraries often target plain win32 for their Windows implementations, and 4) as the person you’re replying to indicated – Microsoft have burned developers too many times by introducing new development paradigms that it then just abandons. Remember XNA? it launched about the same time as Vista, and was being discontinued by Windows 8. Lack of continuity like that is why most devs won’t blindly follow Microsoft’s current flavour of the month.

        I just wish MS had continued to invest that effort in improving Win32’s API instead of continually reinventing the wheel and fragmenting the developer base over and over. As has already been mentioned above – there is a perfectly good GetSysColor() function, but instead of simply updating that API to support ‘accent color’, they have chosen to expose an entirely different interface, with multiple layers of hoops and error checking to be performed. Looking at how much effort is involved to retrieve such a basic parameter, I can see why some devs resort to the “hmm.. is there just like… a registry setting I can read to get that?”.

        In this case it would literally be less code to instantiate a visual element that used the user’s accent color, read the color value directly from the screen, and kill the element, than just to ask Windows what the color is…..

        /rant over.

        1. John ( other John ) says:

          I will probably never fully explain it, but I fell for COM.

          I’m perennially pleased COM lives on, courtesy Don B and Azure…

          Mkay, real reason I fell for COM: The moment I read NT came with Windows Transaction Server I got a look at the real world I wanted to understand. On a budget I could, and don’t junior status, had to afford myself. At least initially.

Comments are closed.

Skip to main content