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)
MyBase.WndProc(msg)
End Sub
Now, we need to 'listen' for the color change:
If msg.Msg = WM_DWMCOLORIZATIONCOLORCHANGED Then
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:
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:
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
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