【问题标题】:Vista/7: How to get glass color?Vista/7:如何获得玻璃颜色?
【发布时间】:2011-04-03 10:02:27
【问题描述】:

你如何使用DwmGetColorizationColor

documentation 表示它返回两个值:

  • 32 位 0xAARRGGBB 包含用于玻璃成分的颜色
  • 一个布尔参数,“如果颜色是不透明的混合”,则为真(不管是什么意思

这是我喜欢的颜色,漂亮的呕吐绿色:

你可以注意到颜色是绿色的,半透明的标题栏(在白色背景下)非常清楚地显示鼻涕颜色:

我尝试从 Windows 获取颜色:

DwmGetColorizationColor(dwCcolorization, bIsOpaqueBlend);

我得到了

dwColorization: 0x0D0A0F04
bIsOpaqueBlend: false

根据文档,该值的格式为AARRGGBB,因此包含:

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

这应该意味着颜色是 (10, 15, 4),不透明度约为 5.1%。

但如果你真的看一下这个 RGB 值,它与我想要的鼻涕绿色相去甚远。这里是

  • (10, 15, 4) 不透明度为零(原始颜色),并且
  • (10,15,4) 不透明度为 5%,白色/棋盘背景:

DwmGetColorizationColor 不是Lime 绿色,而是返回几乎完全透明的黑色

所以问题是:如何在 Windows Vista/7 中获得玻璃颜色

我尝试使用DwmGetColorizationColor,但效果不佳。


一个person with same problem, but a nicer shiny picture来吸引你的松鼠:

所以,归结为—— DwmGetColorizationColor 完全是 无法用于尝试的应用程序 将当前颜色应用到 不透明的表面。


我爱this guy's screenshots 比我的好得多。以他的截图为模板,我又制作了一些火花:

对于最后两个屏幕截图,alpha 混合芯片是真正的部分透明 PNG,与浏览器的背景混合。凉爽的! (我真是个极客)

编辑 2:必须将它们排列成彩虹色。 (我真是个极客)

编辑 3:现在我当然要添加黄色。


未记录/不受支持/脆弱的解决方法

在入口点 137 处存在来自 DwmApi.dll 的未记录导出,我们将其称为 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;
}

我们对第一个参数感兴趣:ColorizationColor

我们也可以从注册表中读取值:

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

因此,您选择了创建 appcompat 问题的毒药。你可以

另见


我已经想问这个问题一年多了。我一直都知道这是不可能回答的,而让任何人真正关注的唯一方法就是拥有彩色截图;开发人员被闪亮的东西所吸引。但不利的一面是,这意味着我必须投入各种工作来制作诱饵。

【问题讨论】:

  • 太闪亮了! /me 将闪亮的物体隐藏在闪亮的东西中。 ...这是一个很好的问题。我希望我知道答案。
  • 关于 Windows API 的一切总是让我兴奋,不管是不是截图(当然,像这样一个写得很好的问题总是更好)。
  • +1 我也喜欢呕吐绿色,因为我碰巧喜欢各种绿色。
  • This question's answer 似乎是唯一能提供正确混合标题栏颜色的正确方法(至少对于 Windows 8/8.1)。

标签: winapi aero user-preferences dwm


【解决方案1】:

A0F040 在你看来如何?


OP 编辑​​:这就是 0xA0F040 在我看来的样子:

【讨论】:

  • 非常牵强。但惊人的接近。
  • 我只是在猜测(实现多字节值处理的旧规则:'如果没有意义,请更改字节顺序')。我对您发布的其他两种颜色进行了测试,结果不再那么好。可能是偶然的机会。
  • 你没有改变字节顺序;你改变了半字节顺序。 (这就是为什么我觉得它如此牵强。)
  • 是的,我看到了他的所作所为;如果这就是微软正在做的事情,我会感到害怕
  • 是的...稍微扩展了规则 :P 无论如何,我注意到 0A0f04 确实是一种非常深的绿色,但是绿色...另外两种颜色似乎也相匹配,但更暗。也许应该以某种方式将 alpha 通道应用于这些值,以获得原始值?
【解决方案2】:

着色颜色!= 选择的基色。这是误导,我知道。

但我很困惑。您借用的图片来自我的帖子,标题为“Retrieving Aero Glass base color for opaque surface rendering”。这不是你想做的吗?我还在帖子中指出了存储所有颜色信息的注册表位置 (HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM) 以供检索。

8 月 26 日编辑

DwmGetColorizationColor (dwmapi.dll) 返回“着色颜色”,它是各种颜色(包括您选择的基色)和着色器逻辑的混合,以实现整体玻璃效果。

您需要/想要的所有颜色信息都可以在上述注册表项中找到。基色、混合中使用的颜色以及生成的着色颜色都在那里。

(以上密钥存在于 Windows Vista 及更高版本上。)

【讨论】:

  • 我想做的。但像你一样,我想避免依赖未记录的函数或注册表项。我希望有人能破译DwmGetColorizationColor 返回的内容。或者解释如何将其转化为与用户选择的内容相关的内容。
  • 我的意思是,如果它是一个完全没有意义的值:那么他们还不如返回一个HANDLE,或其他一些不透明的值。但它记录为“AARRGGBB” - 所以这一定意味着某事
  • 文档还说它是 GDI+ 颜色值。在 GDI+ 中,当它与本机 API 调用混合时,使用预乘 alpha 是很常见的。但是当我除以 alpha 时,它的结果并不完全正确。有时aa 值低于任何rrggbb。我还注意到你永远不会得到低于 0x0d (13) 或高于 0xd9 (217) 的 alpha。也许它是范围压缩的,就像 UIRibbon 使用的那样。
  • 不过,从积极的一面来看,依赖包含视觉偏好的注册表项很少像使用未记录行为的许多其他示例那样具有潜在的致命性,这实际上可能会使您的应用程序(甚至 explorer.exe)崩溃。在这里,您可以安全地确定注册表项是否存在,如果不存在,您可以优雅地失败(但您可能几乎永远不会在 Vista/7 系统上这样做)。可能发生的最糟糕的事情是颜色值错误。所以我认为我可以接受注册表方法。
  • @Rafael Rivera 这是一个先有鸡还是先有蛋的问题。 Microsoft 无法更改其内部实现细节,因为编写不佳的程序取决于实现细节。因此,微软必须为这些设计不佳的程序创建兼容性垫片。人们认为微软应该继续打破违反规则的应用程序;但微软无法做到这一点,因为当时“Windows 8 破坏了我的应用程序”,而不是准确的“我的应用程序总是被破坏,而且它曾经工作过,真是太神奇了”。 blogs.msdn.com/b/oldnewthing/archive/2003/12/24/45779.aspx
【解决方案3】:

我相信我已经解决了 Aero Color 问题。 ColorizationColor 给出的颜色实际上是 AARRGGBB,但它并没有以你想象的方式使用。为了解决最终的颜色,您还需要获取颜色强度,如下所示:http://www.codeproject.com/Articles/610909/Changing-Windows-Aero-Color

第一步是解析 AARRGGBB。然后获取生成的 RGB 并转换为 HSV。全亮度下的纯色相加饱和度是基色。现在在纯色相和饱和度之上将值叠加为 Alpha 的灰度以获得 Aero 颜色。然后将该颜色覆盖在框架颜色上:rgb(235, 235, 235) 以强度获得最终的 Composite Aero 颜色结果。

最后,我还提供了一个示例,说明如何提取与 Aero 框架颜色匹配的可用工具栏颜色,但始终适用于黑色文本和其他基本 Aero 功能。这是通过将强度限制为 35% 来实现的。

这是数学:

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

【讨论】:

  • 很遗憾这是错误的(至少在 Win 8.1 上)。使用颜色 #964C3361 和平衡 65 这会导致帧颜色为 #FFAC9BBB,而实际帧实际上是 #FF7D6D8B。太轻了。
猜你喜欢
  • 2012-10-15
  • 2011-05-21
  • 1970-01-01
  • 2010-11-03
  • 1970-01-01
  • 2010-10-02
  • 1970-01-01
  • 2015-12-19
  • 1970-01-01
相关资源
最近更新 更多