本文介绍了如何在 Windows 8.1 中获取 WPF 窗口的标题栏颜色?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

To customize window's appearance using WindowChrome class, I would like to get the title bar color of WPF window in Windows 8.1.

首先,我试过了

SystemParameters.WindowGlassColor

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

But this property but does not include correct alpha value (it is always 255).

其次,我尝试了函数:

DwmGetColorizationColor

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

It seemed to work fine at first. The return value has correct color information including alpha channel. However, as changing "Color intensity" by slide bar in "Color and Appearance" dialog, the return value will go away from the actual one and indicate a weird color.

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

So, does anyone have idea on alternate method or workaround?

推荐答案

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

I found a solution. Actually, the basic point has been already discussed.

顺序是:

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

这篇关于如何在 Windows 8.1 中获取 WPF 窗口的标题栏颜色?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 22:24
查看更多