Click here to Skip to main content
Click here to Skip to main content

DWM - Colorization Color Handling Using DWMGetColorizationColor

By , 24 Mar 2008
 

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.

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.

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

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

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?

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:

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:

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)

About the Author

o m n i
Software Developer (Junior) Omnicode Inc
United States United States
Member
I am currently a small .Net Hobbyist developing applications for free.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionDoes it work while changing the color?memberPacMani14 Apr '09 - 7:31 
Hello Omnicoder,
first, thanks for the help of getting out that DWM color key in the registry. Do you know if it is possible to recieve a message while the user is changing the color, before he clicks on Ok?
AnswerRe: Does it work while changing the color?memberOmnicoder29 Aug '09 - 6:59 
The only thing I can think of is intercept whatever message the color change dialog sends to change the color.
 
Have you tried the Krypton Toolkit? http://www.componentfactory.com/free-windows-forms-controls.php

QuestionModify the colormemberTommyB89 Jan '09 - 5:59 
Is there any way to change the color?
I can change the registry key (works, but requires reboot). Also I tried to post the message (broadcast) without results.
 
I want to change it like in control panel, where changes are applied instantly, and in best case without saving it, so the default color is applied back after a reboot (if my application crashes, is terminated abnormally, ...)
 
Thanks in advance and sorry for my english
AnswerRe: Modify the colormemberOmnicoder24 Jan '09 - 10:12 
I believe there is a system function (in shell32?) that tells the system to update stuff like this. As far as not 'actually' changing it I don't believe thats possible but I suppose you could have a small runner application that runs your application so if it crashes the runner can change the color back. I will look at what function refreshes the color.
GeneralregistrymemberJason Witty24 Mar '08 - 11:23 
would you be able to gain access to the registry as displayed in vista in a compiled app?
 

GeneralRe: registry [modified]memberOmnicoder24 Mar '08 - 12:14 
You mean changing the color?
 
modified on Wednesday, December 24, 2008 9:37 PM

GeneralRe: registrymemberJason Witty24 Mar '08 - 12:25 
no i mean if the app was not "ran as administrator" (boop) would you have rights to access the registry using your method.
 

GeneralRe: registrymemberOmnicoder24 Mar '08 - 14:16 
Yea. I actually did all of my testing not running as admin
Questioncan you add a space?memberJason Witty24 Mar '08 - 11:15 
can you add a space between the words Handling/DWMGetColorizationColor, your article goes out in the codeproject rss feeds and that does not wrap well.
 

AnswerRe: can you add a space?memberOmnicoder24 Mar '08 - 11:18 
Done Smile | :)
GeneralRe: can you add a space?memberJason Witty24 Mar '08 - 11:21 
thanks ! Smile | :)
 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 24 Mar 2008
Article Copyright 2008 by o m n i
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid