3

I'm working on a WPF application and I'm working with a Telerik dialog control that displays like a Window but is not actually a Window object.

Since it's not an actual Window (but it looks and acts like one) it's style doesn't match the rest of dialogs used in my application.

So, I have created a template for this dialog and I am in the process of assigning System colors to the template so that the dialog uses the same colours and has the same look and feel as a normal Window.

For some reason I cannot find the System Color for the "Window Color" (not the window background color, that one's pretty easy to find...I'm talking about the actual window color...the frame and header of the window)

I have gone through all of the System.Windows.SystemColors but can't find the system color that defines the "Window Color"... like I said, I don't want a reference to the "window's background color".

I was wondering if anyone knew about how to retrieve this color.

Edit: Here is some code that I have implemented in my attempts to determine which system color is used for the Window Color.

The following WPF code is a bunch of Borders whose backgrounds are set to each System Color available...a TextBlock with the name of the System Color is within each Border.

If you want to check it out for yourself, put the following into a Window or something so that you can see it:

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

Thanks for your help

Edit: Here is the VB.NET version of the C# solution posted. You can bind to the WindowColorBrush property to set things like the Background color of controls in your WPF styles:

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
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Frinavale
  • 3,908
  • 10
  • 44
  • 74
  • 2
    Are you looking to grab the Aero glass tint color in Windows Vista and 7? If so you'll want to look at this: http://stackoverflow.com/questions/3560890/vista-7-how-to-get-glass-color – BoltClock Oct 12 '11 at 19:07
  • Yes...after reading that link I'm very discouraged about this. Why oh why couldn't the just use a Normal Window! – Frinavale Oct 12 '11 at 19:30
  • BoltClock, post this as an answer and I'll mark it as such. At this time I've decided to take a different approach to the problem. I've decided not to try to style a non-window control as a window. Instead, I'm going to write my own Telerik dialog that inherits from Window. – Frinavale Oct 12 '11 at 19:44
  • Well it isn't super difficult to grab the color even in a managed framework like WPF. In fact I just did this in my own app, and I think the developers of [MetroTwit](http://metrotwit.com) use something similar. Hang on while I write an actual answer with details (C# code)... – BoltClock Oct 12 '11 at 19:51

1 Answers1

4

Are you looking to grab the Aero glass tint color in Windows Vista and 7? You can access that with an undocumented P/Invoke as discussed in this question and some other pages that it links to, most importantly this article.

Specifically, you need to use the following Windows function:

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

With DWMCOLORIZATIONPARAMS defined as such:

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

While that struct looks like a lot, you'll only be interested in its ColorizationColor.

Here's how I convert that value to a System.Windows.Media.Color for use in WPF/Silverlight (all it takes is really a handful of bit shifts):

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

The only issue with this that the linked question poses is that, well, it's undocumented, so it could change or go away at any time (I don't even know for certain if this will work in Windows 8's desktop interface, but I believe it should). However, this technique works for me, and it's currently used in other WPF apps like MetroTwit as well, to amazing effect. And really, I'd rather use this than drill into the registry.

Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • Thanks for this. I played with it after converting the C# code into a VB.NET class that I could bind to in my XAML....after further reading I discovered that the dwmapi.dll is not available on Windows XP...we are supporting that OS. – Frinavale Oct 12 '11 at 21:07
  • I posted the VB.NET class that I implemented based on your C# code in this solution – Frinavale Oct 12 '11 at 21:10
  • Windows XP doesn't have Aero glass at all, which is why I specifically mentioned Vista and 7. You'll have to go a totally different route for that... – BoltClock Oct 12 '11 at 21:27