1

我正在尝试为应用程序获得媒体播放器玻璃效果,但我面临着各种障碍。是我,还是API?

我首先调用:

MARGINS margins = { -1, -1, -1, -1 };
HRESULT result = ::DwmExtendFrameIntoClientArea(m_hWnd, &margins);

并将背景擦除为黑色:

OnEraseBkgnd

一切都很好,直到我添加了一个编辑框。使用 EditBox,黑色文本出现的地方被玻璃代替。这个问题与 ComboBoxEx 等更高级的控件不成比例。那些开始看起来像一团糟。

这种方法的优点是 alpha 混合图像看起来不错。并逐渐融入玻璃。

编辑框的解决方案似乎是使用带有 LWA_COLORKEY 的 WS_EX_LAYERED 并使用一些可怕的颜色进行玻璃遮罩,并将背景擦除为该颜色。不幸的是,这破坏了其他事情。图标上的 alpha 混合看起来超级难看,阴影混合成放射性绿色,而且玻璃本身变得可点击,即使我在窗口上没有 WS_EX_TRANSPARENT 样式。

第三个建议是使用 GDI+ 进行自定义合成,但这似乎是一种不好的方法,因为 GDI+ 是一种软件回退,我找不到如何将 EditBox 或 ComboBoxEx 渲染为可用于合成的图像的方法之后。

我错过了什么吗?

SO的消息来源似乎也面临同样的问题: link1 link2

4

3 回答 3

3

Kenny Kerr 写了一篇关于在玻璃上显示控件的优秀文章,以编辑控件为例:

http://weblogs.asp.net/kennykerr/archive/2007/01/23/controls-and-the-desktop-window-manager.aspx

于 2010-12-06T15:38:29.553 回答
2

简单的答案是,你不能这样做。

所有标准控件都使用正常的 GDI 调用呈现自己。正常的 GDI 调用是不知道 alpha 的,并且大多将 alpha 通道设置为零。

更复杂的答案是,您可以:网上有一些样品,其中标准对照与航空玻璃混合。它们分为两个基本类别:

  • WinForms (.NET) 示例。WinForms 实际上并不使用本机控件 - WinForms 控件都是重写版本,除其他功能外,还使用 ​​alpha 感知例程进行 blit。这个例子简单得令人沮丧,让我意识到微软是多么讨厌原生开发者。

  • 子类化示例:让常规/原生控件在航空玻璃上绘制的唯一方法是子类化控件,捕获 WM_PAINT 消息以创建 DIBBitmap,调用 WM_PRINT 将控件内容渲染到其上。使用 DWM 功能修复 Alpha 通道数据。使用 AlphaBlend 自己绘制生成的 alpha'd bitap。

This article on CodeProject contains a reference implementation that subclasses most of the standard controls rather well.

于 2010-12-07T09:34:25.140 回答
0

尝试将编辑框等控件上的文本/前景色更改为“几乎是黑色”(如#010101)。然后,您应该能够跳过除图像/图标的 alpha 透明度之外的其他渲染问题。

编辑:绘制其他东西 - 可能是一些奇怪的处理兼容性的方法,但是经典应用程序默认不是玻璃主题......不知道。如果可能的话,尽量避免自己画东西。

于 2010-12-06T14:37:16.673 回答