【问题标题】:Windows Aero: What color to paint to make "glass" appear?Windows Aero:要画什么颜色才能使“玻璃”出现?
【发布时间】:2010-12-24 14:48:37
【问题描述】:

我必须在客户区涂上什么颜色才能使 玻璃 出现?

我已使用以下方法将表单的框架扩展到客户区:

DwmExtendFrameIntoClientArea(self.Handle, margins);

我找不到任何来自 Microsoft 的官方文档,说明 DWM 将寻找什么 color 和/或 alpha 来替换玻璃。 DwmExtendFrameInClientArea 上的文档甚至没有提到需要自定义颜色。甚至需要特殊颜色只是传闻和神话。

我能找到的最接近的是 MSDN 上的一个主题:

Custom Window Frame Using DWM

要使扩展帧可见,每个扩展帧边下的区域必须具有 alpha 值为 0 的像素数据。

更新:还有一篇博文:

Windows Vista for Developers – Part 3 – The Desktop Window Manager

碰巧 RGB 黑色 (0x00000000) 的位模式与 100% 透明 ARGB 的位模式相同,因此您实际上可以使用“黑色”GDI 画笔进行绘制,并假设您已指示 DWM 模糊涂漆区域,结果将是所需的玻璃效果。

如果我按字面意思理解(alpha 值为 0 的像素数据),我会构造一个 alpha 值为零的颜色,并在扩展区域中绘制它:

Color fillColor = Color.FromArgb(0, 0, 0, 0); //(a, r, g, b)
e.Graphics.FillRectangle(new SolidBrush(fillColor), e.ClipRectangle);

但是玻璃效果没有出现:


如果我忽略引用的 MSDN 主题,而是使用完全不透明的黑色(而不是完全透明的黑色):

Color fillColor = Color.FromArgb(255, 0, 0, 0); //(a, r, g, b)
e.Graphics.FillRectangle(new SolidBrush(fillColor), e.ClipRectangle);

玻璃效果确实出现了:

然后我相信 不透明黑色 是 DWM 将寻找替换为玻璃的像素值。

但是我如何在玻璃区域上绘制黑色物品


我已经测试在玻璃区域上画一个黑色的矩形,旁边有一个。奇怪的是,矩形没有出现,而圆形却出现了;两者都是相同的颜色:

Brush b = new SolidBrush(Color.FromArgb(255, 0, 0, 0));
e.Graphics.FillRectangle(b, 11, 11, 32, 32);
e.Graphcis.FillEllipse(b, 43, 11, 32, 32);

那么世界上到底发生了什么?什么是适合在扩展框架区域绘制以使玻璃出现的颜色?


更新 2

使用Adisak 的建议来准确隔离 Aero 的愚蠢之处,这里我在黑色圆圈内画了一个黑色矩形:

FillEllipse 不支持画黑圈吗?


更新 3

Pondidum 想知道用 透明黑色 调用 Graphics.Clear 是否会使玻璃可见:

e.Graphics.Clear(Color.FromArgb(0,0,0,0));

确实有效,但您仍然无法在玻璃上绘制不透明的黑色项目:


更新 4

查看Microsoft's Vista Bridge Library(围绕不会添加到 .NET 的 Vista 功能的托管包装器),他们只能设法让扩展玻璃框架在 WPF 表单上工作,而不是在 WinForms 上工作。

另见

【问题讨论】:

  • 这可能正确也可能不正确,但从您的测试中可以看出,不透明的黑色矩形可能会以航空效果呈现。您可以尝试在黑色椭圆的中间渲染一个不透明的黑色矩形,看看它是否是透明的。
  • 要画黑色不透明的东西,可以试试 254,0,0 吗?
  • @karoberts:你的意思是 (254, 0,0,0),因为 (254,0,0) 是红色的。
  • @Ian:是的,我的意思是(1,1,1),略高于纯黑色
  • 我看到一个红色像素,我想把它涂成黑色。

标签: windows gdi+ aero dwm


【解决方案1】:

您在上面链接到的blog posts 之一对此进行了讨论。原生解决方案是使用SetLayeredWindowAttributes 将颜色键从黑色切换。

【讨论】:

  • SetLayeredWindows 属性将一组问题换成另一组问题。它改变了键的颜色。 “选择合适的颜色是最难的部分。” “字体平滑将......与透明度颜色而不是实际背景混合。” “......指定一种不太可能被任何控件使用的颜色......”假设我想以正确的方式做事。或者假设我在追求知识。无论哪种方式,我仍然想知道要绘制什么颜色/alpha 以使 玻璃 出现。
  • “同样重要的是,您指定的颜色不太可能被绘制在窗口上的任何控件使用。”。这是一个可怕的解决方案。如果我把它放在一个库/图形编辑器中怎么办?
【解决方案2】:

尝试将表单的 TransparencyKey 设置为 Color.FromArgb(1,1,1) (或您选择的其他合适的值),然后将表单的背景色(或您想要成为玻璃的部分)设置为相同的值。

这就是我如何让它在不让我的所有黑色文本透明/玻璃的情况下工作。

不过,我一直想不通如何在玻璃上画出“发光”的文字。它后面总是有一个黑色的矩形。

【讨论】:

  • 我不一定在 .NET 中使用 WinForms。为了绘制(标题)文本,您需要使用主题 api。它在其后面绘制适当的黑色文本和白光。
  • 啊,对不起,我以为是 WinForms。
  • 嗯,有本地的等价物吗?
【解决方案3】:
Color fillColor = Color.FromArgb(0, 0, 0, 0); //(a, r, g, b)
e.Graphics.FillRectangle(new SolidBrush(fillColor), e.ClipRectangle);

这其实很有趣。这意味着您正在绘制一些完全透明的东西 - 所以这绝对不会改变任何东西! :-)

猜想:如果黑色 (0,0,0) 应该表示“玻璃”,那么绘制 (1,1,1) 来获得(几乎)黑色怎么样?

【讨论】:

  • e.Graphics.Clear(Color.FromArgb(0, 0, 0, 0)); 也行不通吗?
  • 我想我可以画出我想要的颜色,但我宁愿画我想要的颜色。
  • 最有趣的是如何解释 alpha 值:应该评估它以混合绘图图元,还是应该替换缓冲区的 alpha 值?
  • @Pondium - 与 e.Graphics.Clear(Color.FromArgb(x, 0, 0, 0)); 相同其中 x 可以是任何东西,因为表单表面通常是 24 位 - alpha(必须)/被忽略。这使得它等于用黑色绘制。然而,当在 av 32 位 BitMap 上使用 .Clear 时,alpha 开始发挥作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-05
  • 1970-01-01
  • 2011-03-21
  • 2011-07-22
  • 2015-12-19
  • 2011-04-03
相关资源
最近更新 更多