Vista/7: How to get glass color?
Asked Answered
U

3

55

How do you use DwmGetColorizationColor?

The documentation says it returns two values:

  • a 32-bit 0xAARRGGBB containing the color used for glass composition
  • a boolean parameter that is true "if the color is an opaque blend" (whatever that means)

Here's a color that i like, a nice puke green: alt text

You can notice the color is greeny, and the translucent title bar (against a white background) shows the snot color very clearly: enter image description here

i try to get the color from Windows:

DwmGetColorizationColor(dwCcolorization, bIsOpaqueBlend);

And i get

dwColorization: 0x0D0A0F04
bIsOpaqueBlend: false

According to the documentation this value is of the format AARRGGBB, and so contains:

AA: 0x0D (13)
RR: 0x0A (10)
GG: 0x0F (15)
BB: 0x04 (4)

This supposedly means that the color is (10, 15, 4), with an opacity of ~5.1%.

But if you actually look at this RGB value, it's nowhere near my desired snot green. Here is

  • (10, 15, 4) with zero opacity (the original color), and
  • (10,15,4) with 5% opacity against a white/checkerboard background:

alt text

Rather than being Lime green, DwmGetColorizationColor returns an almost fully transparent black.

So the question is: How to get glass color in Windows Vista/7?

i tried using DwmGetColorizationColor, but that doesn't work very well.


A person with same problem, but a nicer shiny picture to attract you squirrels: alt text

So, it boils down to – DwmGetColorizationColor is completely unusable for applications attempting to apply the current color onto an opaque surface.


i love this guy's screenshots much better than mine. Using his screenshots as a template, i made up a few more sparklies:

alt text

alt text

alt text

alt text

alt text

alt text

For the last two screenshots, the alpha blended chip is a true partially transparent PNG, blending to your browser's background. Cool! (i'm such a geek)

Edit 2: Had to arrange them in rainbow color. (i'm such a geek)

Edit 3: Well now i of course have to add Yellow.


Undocumented/Unsupported/Fragile Workarounds

There is an undocumented export from DwmApi.dll at entry point 137, which we'll call DwmGetColorizationParameters:

HRESULT GetColorizationParameters_Undocumented(out DWMCOLORIZATIONPARAMS params);

struct DWMCOLORIZATIONPARAMS
{
   public UInt32 ColorizationColor;
   public UInt32 ColorizationAfterglow;
   public UInt32 ColorizationColorBalance;
   public UInt32 ColorizationAfterglowBalance;
   public UInt32 ColorizationBlurBalance;
   public UInt32 ColorizationGlassReflectionIntensity;
   public UInt32 ColorizationOpaqueBlend;
}

We're interested in the first parameter: ColorizationColor.

We can also read the value out of the registry:

HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM
    ColorizationColor: REG_DWORD = 0x6614A600

So you pick your poison of creating appcompat issues. You can

See also


i've been wanting to ask this question for over a year now. i always knew that it's impossible to answer, and that the only way to get anyone to actually pay attention is to have colorful screenshots; developers are attracted to shiny things. But on the downside it means i had to put all kinds of work into making the lures.

Underdog answered 24/8, 2010 at 20:47 Comment(4)
Oooo Shiny! /me goes to hide shiny object in stash of shinies. ... It's a good question. I wish I knew the answer.Methylal
Everything about the Windows API always excites me, screenshots or not (but of course a well-written question like this is always much nicer).Parasite
+1 I like puke green too, because I just happen to like all shades of green.Dilatometer
This question's answer seems to be the only correct one which gives the proper blended titlebar color (at least for Windows 8/8.1).Mutation
D
11

Colorization color != the base color chosen. It's misleading, I know.

But I'm confused. The image you borrowed was from my post entitled "Retrieving Aero Glass base color for opaque surface rendering". Is this not what you want to do? I also indicated in the post the registry location in which all the color information is stored (HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM) for retrieval purposes.

Edited 8/26

DwmGetColorizationColor (dwmapi.dll) returns the "colorization color", which is a blend of various colors (incl. your selected base color) and shader logic to achieve the overall glass effect.

All the color information you need/want can be found in the registry key noted above. The base color, the colors used in blending, and the resulting colorization color are all there.

(The key above is present on Windows Vista and above.)

Demy answered 24/8, 2010 at 23:16 Comment(11)
It is what i want to do. But like you, i would like to avoid relying on undocumented functions or registry keys. i am hoping someone can decipher what DwmGetColorizationColor returns. Or explain how to turn it into something related to what the user picked.Underdog
i mean, if it's a completely meaningless value: then they might as well have returned a HANDLE, or some other opaque value. But it was documented as "AARRGGBB" - so that must mean something.Underdog
The documentation also says it's a GDI+ color value. It is common in GDI+, when it mixes with native API calls, to use pre-multiplied alpha. But when i divide by the alpha it doesn't work out quite right. Sometimes the aa value is lower than any rr, gg, or bb. i've also noticed that you'll never get an alpha lower than 0x0d (13), or higher than 0xd9 (217). Perhaps it's range compressed, like the UIRibbon uses.Underdog
On the positive side, though, relying on registry keys containing visual preferences is seldom as potentially fatal as many other examples of using undocumented behaviour, which literally can crash your application (or even explorer.exe). Here you can safely determine if the registry key exists or not, and if not, you can fail gracefully (but you will probably almost never do this on a Vista/7 system). And the very worst thing that can happen, is that a colour value gets wrong. So I think that I could live with the registry approach.Parasite
@Andreas Granted, i could come up with unsupported workarounds. But i was hoping someone who knows something about DWM would stumble across this question and have the actual answer.Underdog
I added a clarifying note about this. I'm still unsure what more you need... all the color information is in the registry.Demy
When the registry information is removed, all that will remain is the documented API.Underdog
The registry is the central store for this information. I wouldn't expect it to go away any time this decade.Demy
Relying on undocumented behavior is a sin; Raymond Chen will have a fit. (blogs.msdn.com/b/oldnewthing/archive/2003/12/24/45779.aspx)Underdog
Microsoft could overhaul the entire interface but history shows Microsoft is lethargically slow to make breaking changes. And it's unlikely this mystery application of yours would apply to later OSes (might not even have glass).Demy
@Rafael Rivera It's a chicken-and-the-egg problem. Microsoft cannot change their internal implementation details, because poorly written programs depends on the implementation details. So then Microsoft has to create compatibility shims for these poorly designed programs. People argue that Microsoft should just go ahead and break apps that break the rules; but Microsoft can't do that, because then "Windows 8 broke my app", rather than the accurate "my app was always broken, and it's amazing it ever worked." blogs.msdn.com/b/oldnewthing/archive/2003/12/24/45779.aspxUnderdog
I
2

I believe I have solved the Aero Color. The color given by ColorizationColor is in fact AARRGGBB but it is not being used in the way that you think at all. And in order to solve the final color, you also need to get the Color Intensity as shown here: http://www.codeproject.com/Articles/610909/Changing-Windows-Aero-Color

First step is to parse AARRGGBB. Then take the resulting RGB and convert to HSV. The pure Hue plus Saturation at full brightness is the base color. Now overlay Value as a grayscale at Alpha over top of pure Hue and Saturation to get the Aero color. Then overlay that color over the frame color: rgb(235, 235, 235) at Intensity to get the final Composite Aero color result.

Lastly, I've also provided an example of how to extract a useable toolbar color that matches the Aero frame color, but will always work with black text and other basic Aero features. This is accomplished by limiting Intensity to 35%.

Here is the math:

  function dwmToRgb() { 
    // Input Values
    var colorizationColor = "a84f1b1b"; // dwmcolor.clrColor = ColorizationColor
    var colorizationColorBalance = 60; // dwmcolor.nIntensity = ColorizationColorBalance 
    var F = 235; // Frame base grayscale color when Transparency is disabled

    // Parse the input values    
    var A = Math.round(parseInt(colorizationColor.substr(0,2),16)/2.55)/100;
    var R1 = parseInt(colorizationColor.substr(2,2), 16);
    var G1 = parseInt(colorizationColor.substr(4,2), 16);
    var B1 = parseInt(colorizationColor.substr(6,2), 16);
    var I = colorizationColorBalance/100;

    // Solve for HSV Value and pure Hue+Sat
    var V = Math.max(R1, G1, B1);
    var R2 = R1*255/V;
    var G2 = G1*255/V;
    var B2 = B1*255/V;

    // Aero Frame Pure Hue: Overlay Value @ Alpha over pure Hue+Sat
    var R3 = Math.round(V+(R2-V)-((R2-V)*A));
    var G3 = Math.round(V+(G2-V)-((G2-V)*A));
    var B3 = Math.round(V+(B2-V)-((B2-V)*A)); 
    var hexRGB3 = "#" + ((1 << 24) + (R3 << 16) + (G3 << 8) + B3).toString(16).slice(1);

    // Aero Frame Composite Color: Overlay RGB3 @ Intensity over Frame base color        
    var R4 = Math.round(R3+(F-R3)-((F-R3)*I));
    var G4 = Math.round(G3+(F-G3)-((F-G3)*I));
    var B4 = Math.round(B3+(F-B3)-((F-B3)*I));   
    var hexRGB4 = "#" + ((1 << 24) + (R4 << 16) + (G4 << 8) + B4).toString(16).slice(1);

    // Aero Toolbar Color: Overlay RGB3 @ max 35% Intensity over Frame base color   
    if (I > 0.35) { I5 = 0.35;} else { I5 = I;}
    var R5 = Math.round(R3+(F-R3)-((F-R3)*I5));
    var G5 = Math.round(G3+(F-G3)-((F-G3)*I5));
    var B5 = Math.round(B3+(F-B3)-((F-B3)*I5));   
    var hexRGB5 = "#" + ((1 << 24) + (R5 << 16) + (G5 << 8) + B5).toString(16).slice(1);
Isley answered 9/4, 2014 at 8:9 Comment(1)
This is unfortunately wrong (at least on Win 8.1). With color #964C3361 and balance of 65 this results in a frame color of #FFAC9BBB when the real frame is actually #FF7D6D8B. It's far too light.Mutation
L
1

How does A0F040 look to you?


OP Edit: This is how 0xA0F040 looks to me:

alt text

Lectionary answered 24/8, 2010 at 20:52 Comment(5)
Very far-fetched. But surprisingly close.Parasite
I'm just guessing (implementing the old rule of multibyte value processing: 'if it doesn't make sense, change the byte order'). I tested it for the other two colors you posted, and the results are not that good anymore. Probably a random chance.Lectionary
You didn't change the byte order; you changed the nibble order. (And that's why I found it so far-fetched.)Parasite
Yeah, i saw what he did; and i would have been terrified if that's what Microsoft was doingUnderdog
Yeah... stretched the rule a bit :P Anyway, I noticed that 0A0f04 is indeed a very dark green, but green nevertheless... The two other colors also seem to be in matching hue, but darker. Maybe the alpha channel should be applied somehow to these values, to get original value?Lectionary

© 2022 - 2024 — McMap. All rights reserved.