如何在Windows 10下获得C#中的确切开始菜单背景颜色?

时间:2016-07-07 07:11:28

标签: c# wpf windows colors

我有一个测试项目,它使用一些未记录的函数来获取“开始”菜单背景颜色:

using System;
using System.Windows;
using System.Windows.Media;
using System.Runtime.InteropServices;

namespace WpfApplication1
{
    public static class AccentColorService
    {
        static class Interop
        {
            // Thanks, Quppa! -RR

            [DllImport("uxtheme.dll", EntryPoint = "#94", CharSet = CharSet.Unicode)]
            internal static extern int GetImmersiveColorSetCount();

            [DllImport("uxtheme.dll", EntryPoint = "#95", CharSet = CharSet.Unicode)]
            internal static extern uint GetImmersiveColorFromColorSetEx(uint dwImmersiveColorSet, uint dwImmersiveColorType, bool bIgnoreHighContrast, uint dwHighContrastCacheMode);

            [DllImport("uxtheme.dll", EntryPoint = "#96", CharSet = CharSet.Unicode)]
            internal static extern uint GetImmersiveColorTypeFromName(string name);

            [DllImport("uxtheme.dll", EntryPoint = "#98", CharSet = CharSet.Unicode)]
            internal static extern uint GetImmersiveUserColorSetPreference(bool bForceCheckRegistry, bool bSkipCheckOnFail);

            [DllImport("uxtheme.dll", EntryPoint = "#100", CharSet = CharSet.Unicode)]
            internal static extern IntPtr GetImmersiveColorNamedTypeByIndex(uint dwIndex);
        }

        public static Color GetColorByTypeName(string name)
        {
            var colorSet = Interop.GetImmersiveUserColorSetPreference(false, false);
            var colorType = Interop.GetImmersiveColorTypeFromName(name);

            var rawColor = Interop.GetImmersiveColorFromColorSetEx(colorSet, colorType, false, 0);

            return FromABGR(rawColor);
        }

        public static Color FromABGR(uint abgrValue)
        {
            var colorBytes = new byte[4];
            colorBytes[0] = (byte)((0xFF000000 & abgrValue) >> 24); // A
            colorBytes[1] = (byte)((0x00FF0000 & abgrValue) >> 16); // B
            colorBytes[2] = (byte)((0x0000FF00 & abgrValue) >> 8);  // G
            colorBytes[3] = (byte)(0x000000FF & abgrValue);         // R

            return Color.FromArgb(colorBytes[0], colorBytes[3], colorBytes[2], colorBytes[1]);
        }
    }
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Color startBackground = AccentColorService.GetColorByTypeName("ImmersiveStartBackground");
            MessageBox.Show("R: " + startBackground.R + ", G: " + startBackground.G + ", B: " + startBackground.B);
        }
    }
}

据我了解,目前没有官方API可以获取Windows 10下的各种主题颜色。我几乎逐字地使用了一个我发现here的小片段。

(确实在Stack Overflow的其他地方提到过。)

我的强调色是设置中列表中显示的第一个蓝色。我关闭了“开始”菜单透明度。

Image

带有此重音的“开始”菜单的颜色为(0,90,158)。

当我运行上面的代码时,显示的结果是:

R:0,G:90,B:157

这不是一个孤立的案例。对于其他强调色,与实际的“开始”菜单背景色相比,颜色通道的差异通常为+/- 2。

我尝试稍微提高饱和度,转换到不同的颜色空间然后再回来,但我所做的一切都没有可靠地产生我在颜色通道中看到的移位。

是否需要对“ImmersiveStartBackground”颜色执行额外的处理步骤才能获得“开始”菜单背景的确切颜色?或者,是否有uxtheme.dll以外的资源可以查询以获得更准确的开始菜单背景?

0 个答案:

没有答案