在Windows 10下,如何获得C#中“开始”菜单的确切背景颜色?
我有一个测试项目,它使用一些未记录的函数来获得开始菜单的背景颜色:在Windows 10下,如何获得C#中“开始”菜单的确切背景颜色?,c#,wpf,windows,colors,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
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);
}
}
}
使用系统;
使用System.Windows;
使用System.Windows.Media;
使用System.Runtime.InteropServices;
命名空间WpfApplication1
{
公共静态类服务
{
静态类互操作
{
//谢谢,库帕!-RR
[DllImport(“uxtheme.dll”,EntryPoint=“#94”,CharSet=CharSet.Unicode)]
内部静态外部int GetImmersiveColorSetCount();
[DllImport(“uxtheme.dll”,EntryPoint=“#95”,CharSet=CharSet.Unicode)]
内部静态外部单元从ColorSetEx获取ImmersiveColorSet(单元dwImmersiveColorSet、单元dwImmersiveColorType、bool bIgnoreHighContrast、单元DWHighContractCacheMode);
[DllImport(“uxtheme.dll”,EntryPoint=“#96”,CharSet=CharSet.Unicode)]
内部静态外部uint GetImmersiveColorTypeFromName(字符串名称);
[DllImport(“uxtheme.dll”,EntryPoint=“#98”,CharSet=CharSet.Unicode)]
内部静态外部单元GetImmersiveUserColorSetPreference(bool bForceCheckRegistry,bool bSkipCheckOnFail);
[DllImport(“uxtheme.dll”,EntryPoint=“#100”,CharSet=CharSet.Unicode)]
内部静态外部IntPtr GetImmersiveColorNamedTypeByIndex(uint dwIndex);
}
公共静态颜色GetColorByTypeName(字符串名称)
{
var colorSet=Interop.GetImmersiveUserColorSetPreference(false,false);
var colorType=Interop.GetImmersiveColorTypeFromName(名称);
var rawColor=Interop.GetImmersiveColorFromColorSetEx(colorSet,colorType,false,0);
从ABGR(rawColor)返回;
}
来自ABGR的公共静态颜色(uint abgrValue)
{
var colorBytes=新字节[4];
colorBytes[0]=(字节)((0xFF000000&abgrValue)>>24);//A
colorBytes[1]=(byte)((0x00FF0000&abgrValue)>>16);//B
colorBytes[2]=(字节)((0x0000FF00&abgrValue)>>8);//G
colorBytes[3]=(字节)(0x000000FF&abgrValue);//R
返回Color.FromArgb(colorBytes[0],colorBytes[3],colorBytes[2],colorBytes[1]);
}
}
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
Color startBackground=AccentColorService.GetColorByTypeName(“浸入式startBackground”);
MessageBox.Show(“R:+startBackground.R+”,G:+startBackground.G+”,B:+startBackground.B);
}
}
}
据我所知,在Windows10下没有获取各种主题颜色的官方API。我几乎一字不差地使用了我找到的一个小片段
(在堆栈溢出的其他地方确实提到了这一点。)
“我的重点颜色”是“设置”下列表中出现的第一个蓝色。我已关闭“开始”菜单的透明度
带有此重音的“开始”菜单的颜色为(0、90、158)
当我运行上述代码时,显示的结果是:
R:0,G:90,B:157
这不是一个孤立的案例。对于其他强调色,与实际的“开始”菜单背景色相比,颜色通道的差异通常为+/-2
我尝试稍微提高饱和度,转换到不同的颜色空间,然后再转换回来,但我所做的一切都没有可靠地产生我在颜色通道中看到的变化
是否需要对“ImmersiveStartBackground”颜色执行额外的处理步骤,以获得开始菜单背景的确切颜色?或者,除了uxtheme.dll之外,是否还有其他资源可以查询,以获得更精确的“开始”菜单背景?还有
SystemParameters.WindowGlassBrush
。看起来也不完全一样。你确定差异不是因为开始菜单是部分透明的吗?@Cody我不确定开始菜单是完全不透明的。我确实禁用了“开始菜单透明度”,但检查这一点是个好主意。为了验证,我在开始菜单下面放了一个黑色矩形和一个白色矩形,并测量了开始菜单在这些点上的颜色。两个区域均为(0,90158)。我认为这表明它不是99%不透明的。我的意思是,如果是这样的话,我希望黑色和白色的底层之间会有一些差异。