【问题标题】:Retrieving the Windows "Window Color"检索 Windows“窗口颜色”
【发布时间】:2011-10-12 18:16:29
【问题描述】:

我正在开发一个 WPF 应用程序,并且我正在使用一个 Telerik 对话框控件,该控件显示为 Window,但实际上不是 Window 对象。

由于它不是一个实际的窗口(但它看起来和行为都像一个窗口),它的样式与我的应用程序中使用的其他对话框不匹配。

因此,我为此对话框创建了一个模板,并且正在为模板分配系统颜色,以便对话框使用相同的颜色并具有与普通窗口相同的外观。

由于某种原因,我找不到“窗口颜色”的系统颜色(不是窗口背景颜色,很容易找到...我说的是实际的窗口颜色...框架和标题窗口)

我已经浏览了所有System.Windows.SystemColors,但找不到定义“窗口颜色”的系统颜色......就像我说的,我不想引用“窗口的背景颜色”。

我想知道是否有人知道如何检索这种颜色。

编辑: 这是我在尝试确定窗口颜色使用哪种系统颜色时实现的一些代码。

下面的 WPF 代码是一堆边框,它们的背景设置为每个可用的系统颜色...一个具有系统颜色名称的 TextBlock 在每个边框内。

如果您想自己查看,请将以下内容放入 Window 或其他东西中以便您可以看到它:

    <ScrollViewer>
    <StackPanel>
       <-- here I had another Stack Panel referencing the Brushes 
       instead of using the Keys. I wanted the application to be dynamic 
       so that if the user changed colors it would be reflected in 
       the application on the fly...-->

        <StackPanel>
            <StackPanel.Resources>
                <Style TargetType="TextBlock">
                    <Setter Property="Foreground" Value="White" />
                    <Setter Property="VerticalAlignment" Value="Center" />
                    <Setter Property="HorizontalAlignment" Value="Center"/>
                    <Setter Property="Effect">
                        <Setter.Value>
                            <DropShadowEffect BlurRadius="4" Color="Black" ShadowDepth="0"/>
                        </Setter.Value>
                    </Setter>
                </Style>
                <Style TargetType="Border">
                    <Setter Property="BorderBrush" Value="Red"/>
                    <Setter Property="BorderThickness" Value="1" />
                    <Setter Property="Margin" Value="2"/>
                    <Setter Property="Height" Value="20"/>
                </Style>
            </StackPanel.Resources>
            <Border>
                <Border.Background>
                    <SolidColorBrush Color="{DynamicResource {x:Static SystemColors.WindowColorKey}}"/>
                </Border.Background>
                <TextBlock Text="SystemColors.WindowColorKey" />
            </Border>
                <Border Background="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}" >
                <TextBlock Text="SystemColors.ActiveBorderBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}" >
                <TextBlock Text="SystemColors.ActiveCaptionBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.ActiveCaptionTextBrushKey}}" >
                <TextBlock Text="SystemColors.ActiveCaptionTextBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.AppWorkspaceBrushKey}}" >
                <TextBlock Text="SystemColors.AppWorkspaceBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" >
                <TextBlock Text="SystemColors.ControlBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" >
                <TextBlock Text="SystemColors.ControlDarkBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.ControlDarkDarkBrushKey}}" >
                <TextBlock Text="SystemColors.ControlDarkDarkBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}" >
                <TextBlock Text="SystemColors.ControlLightBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.ControlLightLightBrushKey}}" >
                <TextBlock Text="SystemColors.ControlLightLightBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" >
                <TextBlock Text="SystemColors.ControlTextBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.DesktopBrushKey}}" >
                <TextBlock Text="SystemColors.DesktopBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.GradientActiveCaptionBrushKey}}" >
                <TextBlock Text="SystemColors.GradientActiveCaptionBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.GradientInactiveCaptionBrushKey}}" >
                <TextBlock Text="SystemColors.GradientInactiveCaptionBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" >
                <TextBlock Text="SystemColors.GrayTextBrushKey" />
            </Border>

            <Border Background="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" >
                <TextBlock Text="SystemColors.HighlightBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" >
                <TextBlock Text="SystemColors.HighlightTextBrushKey" />
            </Border>

            <Border Background="{DynamicResource {x:Static SystemColors.HotTrackBrushKey}}" >
                <TextBlock Text="SystemColors.HotTrackBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.InactiveBorderBrushKey}}" >
                <TextBlock Text="SystemColors.InactiveBorderBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.InactiveCaptionBrushKey}}" >
                <TextBlock Text="SystemColors.InactiveCaptionBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.InactiveCaptionTextBrushKey}}" >
                <TextBlock Text="SystemColors.InactiveCaptionTextBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.InfoBrushKey}}" >
                <TextBlock Text="SystemColors.InfoBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.InfoTextBrushKey}}" >
                <TextBlock Text="SystemColors.InfoTextBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.MenuBrushKey}}" >
                <TextBlock Text="SystemColors.MenuBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.MenuBarBrushKey}}" >
                <TextBlock Text="SystemColors.MenuBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.MenuHighlightBrushKey}}" >
                <TextBlock Text="SystemColors.MenuHighlightBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.MenuTextBrushKey}}" >
                <TextBlock Text="SystemColors.MenuTextBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.ScrollBarBrushKey}}" >
                <TextBlock Text="SystemColors.ScrollBarBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" >
                <TextBlock Text="SystemColors.WindowBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" >
                <TextBlock Text="SystemColors.WindowFrameBrushKey" />
            </Border>
            <Border Background="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" >
                <TextBlock Text="SystemColors.WindowTextBrushKey" />
            </Border>
        </StackPanel>
    </StackPanel>
</ScrollViewer>

感谢您的帮助

编辑: 这是发布的 C# 解决方案的 VB.NET 版本。 您可以绑定到 WindowColorBrush 属性以设置 WPF 样式中控件的背景颜色等内容:

Public Class WindowsBackgroundRetriever
Implements System.ComponentModel.INotifyPropertyChanged

<Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Sequential)> _
Public Structure DWMCOLORIZATIONPARAMS
    Public ColorizationColor As UInt32
    Public ColorizationAfterglow As UInt32
    Public ColorizationColorBalance As UInt32
    Public ColorizationAfterglowBalance As UInt32
    Public ColorizationBlurBalance As UInt32
    Public ColorizationGlassReflectionIntensity As UInt32
    Public ColorizationOpaqueBlend As UInt32
End Structure
Private cParams As New DWMCOLORIZATIONPARAMS

<Runtime.InteropServices.DllImport("dwmapi.dll", EntryPoint:="#127")> _
Private Shared Sub DwmGetColorizationParameters(ByRef dp As DWMCOLORIZATIONPARAMS)
End Sub

Private _windowColor As Color
Public Property WindowColor As Color
    Get
        Return _windowColor
    End Get
    Set(ByVal value As Color)
        _windowColor = value
        RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("WindowColor"))
    End Set
End Property
Private _windowColorBrush As SolidColorBrush
Public Property WindowColorBrush As SolidColorBrush
    Get
        If _windowColorBrush Is Nothing Then
            _windowColorBrush = New SolidColorBrush(WindowColor)
        End If

        Return _windowColorBrush
    End Get
    Set(ByVal value As SolidColorBrush)
        _windowColorBrush = value
        RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("WindowColorBrush"))
    End Set
End Property

Public Sub New()
    DwmGetColorizationParameters(cParams)

    Dim r = BitConverter.GetBytes(cParams.ColorizationColor >> 16)
    Dim g = BitConverter.GetBytes(cParams.ColorizationColor >> 8)
    Dim b = BitConverter.GetBytes(cParams.ColorizationColor)

    WindowColor = Color.FromArgb(BitConverter.GetBytes(255)(0), r(0), g(0), b(0))
End Sub

Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
End Class

【问题讨论】:

  • 您是否希望在 Windows Vista 和 7 中获取 Aero 玻璃色调?如果是这样,你会想看看这个:stackoverflow.com/questions/3560890/…
  • 是的...阅读该链接后,我对此感到非常沮丧。为什么哦为什么不能只使用普通窗口!
  • BoltClock,将此作为答案发布,我会这样标记。在这个时候,我决定采取不同的方法来解决这个问题。我决定不尝试将非窗口控件设置为窗口。相反,我将编写我自己的继承自 Window 的 Telerik 对话框。
  • 即使在像 WPF 这样的托管框架中,获取颜色也不是很困难。事实上,我只是在自己的应用程序中做到了这一点,我认为MetroTwit 的开发人员使用了类似的东西。等我写一个带有细节的实际答案(C#代码)......

标签: .net wpf windows


【解决方案1】:

您是否希望在 Windows Vista 和 7 中获得 Aero 玻璃色调?您可以使用this question 中讨论的未记录的 P/Invoke 以及它链接到的其他一些页面(最重要的是 this article)来访问它。

具体来说,需要用到以下Windows函数:

// In a static NativeMethods class
[DllImport("dwmapi.dll", EntryPoint = "#127")]
static extern void DwmGetColorizationParameters(ref DWMCOLORIZATIONPARAMS dp);

DWMCOLORIZATIONPARAMS 定义如下:

[StructLayout(LayoutKind.Sequential)]
public struct DWMCOLORIZATIONPARAMS
{
    public UInt32 ColorizationColor;
    public UInt32 ColorizationAfterglow;
    public UInt32 ColorizationColorBalance;
    public UInt32 ColorizationAfterglowBalance;
    public UInt32 ColorizationBlurBalance;
    public UInt32 ColorizationGlassReflectionIntensity;
    public UInt32 ColorizationOpaqueBlend;
}

虽然该结构看起来很多,但您只会对它的 ColorizationColor 感兴趣。

以下是我如何将该值转换为 System.Windows.Media.Color 以在 WPF/Silverlight 中使用(实际上只需要少量位移):

var cParams = new DWMCOLORIZATIONPARAMS();
NativeMethods.DwmGetColorizationParameters(ref cParams);

var windowColor = Color.FromArgb(
    (byte) 255, 
    (byte)(cParams.ColorizationColor >> 16), 
    (byte)(cParams.ColorizationColor >> 8), 
    (byte) cParams.ColorizationColor
);

链接问题提出的唯一问题是,它没有记录在案,因此它可能随时更改或消失(我什至不确定这是否适用于 Windows 8 的桌面界面,但我相信它应该)。但是,这种技术对我很有效,而且它目前也用于其他 WPF 应用程序,如MetroTwit,效果惊人。实际上,我宁愿使用它也不愿深入注册表。

【讨论】:

  • 谢谢。在将 C# 代码转换为可以在我的 XAML 中绑定的 VB.NET 类后,我使用了它……进一步阅读后,我发现 dwmapi.dll 在 Windows XP 上不可用……我们支持它操作系统。
  • 我在此解决方案中发布了我根据您的 C# 代码实现的 VB.NET 类
  • Windows XP 根本没有 Aero 玻璃,这就是我特别提到 Vista 和 7 的原因。你必须走一条完全不同的路线……
猜你喜欢
  • 2011-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-07
  • 2011-07-12
  • 2016-07-22
  • 2010-11-22
  • 1970-01-01
相关资源
最近更新 更多