我们正在开发一个皮肤应用程序,在它的大部分窗口上都有各种圆边。我正在使用窗口区域来定义非矩形形状,但几乎每个人都反对由此导致的锯齿状混叠,因为像素只能是完全不透明或完全透明的。
我想出了一个使用分层窗口的解决方案,但我们希望确保它可以在各种系统上运行(并希望运行良好),我想看看是否有人有更好的想法或方法优化我正在做的事情。我知道分层窗口需要win2000或更高版本,这很好,因为这已经是其他原因的要求。从一些基本测试来看,它在 Vista 上看起来没问题,但这还不能保证。
这就是我所做的:我有一个窗口,称之为 A,带有控件和文本以及包含该窗口的任何内容。我将窗口 B 作为窗口 A 的子窗口,但它具有 WS_POPUP 样式而不是 WS_CHILD,因此它可以将自身定位在 A 的区域之外并绘制在 A 的控件之上。窗口 B 也有 WS_EX_LAYERED 样式,在初始化时,我调用带有 ULW_ALPHA 标志的UpdateLayeredWindow和带有 32 位位图和 alpha 通道的源 DC,以使其使用每个像素的 alpha 进行绘制。
用于窗口 B 的源 DC 中的位图几乎只是窗口边框周围的像素,我希望将其从窗口的背景平滑地混合为完全透明的像素。我会跳过整个两个窗口的方法,只使用一个分层窗口,除了当你使用 UpdateLayeredWindow 时,它是从保存在内存中的缓冲区中绘制的,而不是典型的 WM_PAINT 消息和所有这些,并试图得到交互式子控件(和子窗口)可以很好地工作,这听起来很麻烦(甚至可能不适用于所有事情)。
所以,它基本上是带有所有子控件的窗口 A 和其他任何东西,窗口 B 直接浮动在它上面,绘制了一个漂亮的平滑边框。我通过移动窗口 B 来响应 WM_MOVE 消息等,并且我禁用了窗口 B,因此它永远无法获得焦点或输入(点击已经通过,因为它的部分不透明度为零,例如大多数它的内部零件,已经被排除在采摘之外)。
对于踢球,这就是这些碎片的样子,以更好地展示我的意思。
所以,它有效,但我不能确定它真的是最好的方法。我有两个问题:
- 这听起来可以接受吗,还是有什么可怕的地方?
- 由于它目前的工作原理,它似乎正在使用一个窗口大小的屏幕外缓冲区(最高可达 1024x768),即使它的极少数像素具有任何非零不透明度数据 - 是否值得开销以及将其切割成单独的边界块并将它们组合在一起的额外复杂性?