Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / Win32

DWM - Colorization Color Handling Using DWMGetColorizationColor

4.18/5 (6 votes)
24 Mar 2008CPOL2 min read 1   617  
Using WM_COLORIZATIONCOLORCHANGED and DWMGetColorizationColor.

Image 1

cc_white.jpg

Introduction

I was trying to make a textbox work on glass, and it was failing miserably. Then, I had the idea to reverse the backcolor and forecolors, making a nice glassy textbox, but it had one problem. If you had the theme set to a white or very bright color, and the form was over a very bright or white color, then the text would be unreadable. The solution I thought of? Detect the glass color, and use a different forecolor if they were using a very bright color scheme. Well, after a long time, I ended up with this code, which actually didn't work for my textbox problem. It turns out, setting the forecolor to anything but white makes it draw lucidly again. The bright side? I did something that I have found no other VB.NET OR C# code samples for. This article will show you how to use the code.

What you will need

  • Windows Vista Home Premium, Business, Enterprise, or Ultimate
  • Visual Studio 2005/2008 (2003 might work)
  • DWM turned on
  • Decent knowledge of how Windows works (event driven)
  • Basic understanding of messages
  • A computer :P

Using the code

The first thing you need to do to use the code is declare the constant to hold the 'Friendly Name' of the event to determine when the color was changed.

VB
Private Const WM_DWMCOLORIZATIONCOLORCHANGED As Integer = 800

Next, we need to handle WndProc. Handling WndProc basically means that we will 'listen' for Windows to pass a message into the message stream.

VB
Protected Overloads Overrides Sub WndProc(ByRef msg As Message) 
'Code
  MyBase.WndProc(msg)
End Sub 

Now, we need to 'listen' for the color change:

VB
If msg.Msg = WM_DWMCOLORIZATIONCOLORCHANGED Then 
'Color was Changed!
End If

Now that we know the user changed the colorization color, we should get the color, and make it a usable color, right?

VB
Dim aarrggbb = _
  My.Computer.Registry.GetValue("HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM", _
  "ColorizationColor", "00000000")
Dim argb = Convert.ToInt32(CLng(aarrggbb.ToString), 10)
Dim argbcol = System.Drawing.Color.FromArgb(argb)

Okay, that was some interesting code, right? Basically, what it did was:

  • Get the current colorization color
  • Convert it from binary to decimal (even though it is in Hex)
  • Make a color out of the decimal copy of the colorization color

Now, we can use the color. In the example project, I use the color to do the following:

VB
PictureBox2.BackColor = System.Drawing.Color.FromArgb(argb)
Label1.Text = System.Drawing.Color.FromArgb(argb).ToString
Label1.ForeColor = System.Drawing.Color.FromArgb(argb)
Button1.Text = argbcol.ToString
Button1.ForeColor = argbcol

In case you don't want to scroll up, here is the project running again:

ccblue.jpg

You can use argbcol in your own applications too, it will represent the DWM color.

One additional piece of info: for the same reason that textboxes don't work on glass, WinForms doesn't handle the alpha of the argbcol correctly when over more then one color is used at once. It will use the form backcolor as its color to be transparent over, which is why the clearest possible glass setting doesn't give white on the form:

cc_white.jpg

It makes this instead. The full code listing is:

VB
Private Const WM_DWMCOLORIZATIONCOLORCHANGED As Integer = 800
Protected Overloads Overrides Sub WndProc(ByRef msg As Message)
    If msg.Msg = WM_DWMCOLORIZATIONCOLORCHANGED Then 
        'Color was Changed! 
        Dim aarrggbb = _
          My.Computer.Registry.GetValue("HKEY_CURRENT_USER\" & _ 
          "Software\Microsoft\Windows\DWM", _
          "ColorizationColor", "00000000")
        Dim argb = Convert.ToInt32(CLng(aarrggbb.ToString), 10)
        Dim argbcol = System.Drawing.Color.FromArgb(argb)
        PictureBox2.BackColor = System.Drawing.Color.FromArgb(argb)
        Label1.Text = System.Drawing.Color.FromArgb(argb).ToString
        Label1.ForeColor = System.Drawing.Color.FromArgb(argb)
        Button1.Text = argbcol.ToString
        Button1.ForeColor = argbcol
    End If 

    MyBase.WndProc(msg)
End Sub

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)