【问题标题】:How to get title bar color of WPF window in Windows 8.1?如何在 Windows 8.1 中获取 WPF 窗口的标题栏颜色?
【发布时间】:2014-08-24 16:52:06
【问题描述】:

要使用 WindowChrome 类自定义窗口的外观,我想在 Windows 8.1 中获取 WPF 窗口的标题栏颜色。

首先,我试过了

SystemParameters.WindowGlassColor 

但是这个属性却不包含正确的 alpha 值(它总是 255)。

其次,我尝试了函数:

DwmGetColorizationColor 

起初它似乎工作正常。返回值具有正确的颜色信息,包括 Alpha 通道。但是,当通过“颜色和外观”对话框中的滑动条更改“颜色强度”时,返回值将与实际值不同,并指示出一种奇怪的颜色。

那么,有人知道替代方法或解决方法吗?

【问题讨论】:

  • @Sheridan 感谢您的建议。我尝试了 SystemParameters.WindowGlassBrush 属性,但结果与 SystemParameters.WindowGlassColor 相同。不透明度始终为 1,颜色会随着“颜色强度”的变化而变化。根据Reference Source,它似乎是用 SystemParameters.WindowGlassColor 实例化的。

标签: c# wpf windows-8


【解决方案1】:

我找到了解决方案。其实基本点已经讨论过了。

顺序是:

  1. 通过 DwmGetColorizationParameters 函数获取参数(未记录的 API)。
  2. 将 colorizationColor 参数转换为忽略 Alpha 通道的颜色。
  3. 准备基础灰色(R=217、G=217、B=217)。
  4. 使用对应于“颜色强度”的 colorizationColorBalance 参数混合两种颜色。

所以,我的代码如下:

public static Color? GetChromeColor()
{
    bool isEnabled;
    var hr1 = DwmIsCompositionEnabled(out isEnabled);
    if ((hr1 != 0) || !isEnabled) // 0 means S_OK.
        return null;

    DWMCOLORIZATIONPARAMS parameters;
    try
    {
        // This API is undocumented and so may become unusable in future versions of OSes.
        var hr2 = DwmGetColorizationParameters(out parameters);
        if (hr2 != 0) // 0 means S_OK.
            return null;
    }
    catch
    {
        return null;
    }

    // Convert colorization color parameter to Color ignoring alpha channel.
    var targetColor = Color.FromRgb(
        (byte)(parameters.colorizationColor >> 16),
        (byte)(parameters.colorizationColor >> 8),
        (byte)parameters.colorizationColor);

    // Prepare base gray color.
    var baseColor = Color.FromRgb(217, 217, 217);

    // Blend the two colors using colorization color balance parameter.
    return BlendColor(targetColor, baseColor, (double)(100 - parameters.colorizationColorBalance));
}

private static Color BlendColor(Color color1, Color color2, double color2Perc)
{
    if ((color2Perc < 0) || (100 < color2Perc))
        throw new ArgumentOutOfRangeException("color2Perc");

    return Color.FromRgb(
        BlendColorChannel(color1.R, color2.R, color2Perc),
        BlendColorChannel(color1.G, color2.G, color2Perc),
        BlendColorChannel(color1.B, color2.B, color2Perc));
}

private static byte BlendColorChannel(double channel1, double channel2, double channel2Perc)
{
    var buff = channel1 + (channel2 - channel1) * channel2Perc / 100D;
    return Math.Min((byte)Math.Round(buff), (byte)255);
}

[DllImport("Dwmapi.dll")]
private static extern int DwmIsCompositionEnabled([MarshalAs(UnmanagedType.Bool)] out bool pfEnabled);

[DllImport("Dwmapi.dll", EntryPoint = "#127")] // Undocumented API
private static extern int DwmGetColorizationParameters(out DWMCOLORIZATIONPARAMS parameters);

[StructLayout(LayoutKind.Sequential)]
private struct DWMCOLORIZATIONPARAMS
{
    public uint colorizationColor;
    public uint colorizationAfterglow;
    public uint colorizationColorBalance; // Ranging from 0 to 100
    public uint colorizationAfterglowBalance;
    public uint colorizationBlurBalance;
    public uint colorizationGlassReflectionIntensity;
    public uint colorizationOpaqueBlend;
}

【讨论】:

  • 查看所有其他具有类似/相同问题的线程,这是使用ColorizationColorBalance 实际给出正确混合颜色的唯一答案。
猜你喜欢
  • 1970-01-01
  • 2017-10-25
  • 2016-08-31
  • 1970-01-01
  • 1970-01-01
  • 2019-01-15
  • 1970-01-01
  • 2011-01-25
  • 2022-08-15
相关资源
最近更新 更多