9

我们正在开发一个皮肤应用程序,在它的大部分窗口上都有各种圆边。我正在使用窗口区域来定义非矩形形状,但几乎每个人都反对由此导致的锯齿状混叠,因为像素只能是完全不透明或完全透明的。

我想出了一个使用分层窗口的解决方案,但我们希望确保它可以在各种系统上运行(并希望运行良好),我想看看是否有人有更好的想法或方法优化我正在做的事情。我知道分层窗口需要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),即使它的极少数像素具有任何非零不透明度数据 - 是否值得开销以及将其切割成单独的边界块并将它们组合在一起的额外复杂性?
4

3 回答 3

3

我发现了一件事:拥有单独的框架片段比拥有一个巨大的框架窗口渲染速度要快得多,中间有一大片空像素。我没有任何实际数字,但只是从尝试两者的快速测试来看,当几个具有全框架窗口的窗口相互重叠时,会有明显的延迟,但是当它们的框架被切割成更小的组件时,它会更快. 拥有具有自己的设备上下文的多个分层窗口的任何开销都不会产生太大的影响,并且拥有大范围的像素(无论是否为空白!)仍然会产生更多的负载。

于 2009-04-15T18:45:40.367 回答
2

我的产品使用分层窗口来绘制我附加到每个窗口的小标签。我使用分层窗口来获得平滑的舍入而没有锯齿。到目前为止,我遇到的唯一令人讨厌的问题是,一些 OpenGL 窗口在没有 DWM 的 Windows XP 和 Vista 上的分层窗口之上乱涂乱画。这是一个低级问题,微软并没有提供太大帮助。您可以通过打开 Google 地球并将您的应用程序拖到主渲染窗口上来重现它,您的分层窗口将消失。

于 2009-04-20T17:52:06.083 回答
1
  1. 不要忘记在 RDP 和 VM (Hyper-V & VMWare) 下进行测试
  2. 在上网本和笔记本电脑上尝试几张 gfx 卡(如果适用)。
于 2009-04-17T15:05:53.887 回答