2009-04-13 111 views
9

我们正在开发一个皮肤应用程序,在其大部分窗口上都有各种圆角边缘。我正在使用窗口区域来定义非矩形形状,但几乎所有人都会对由此引起的锯齿形锯齿进行反射,因为像素只能是完全不透明或完全透明的。使用分层窗口创建平滑窗口边界

我已经想出了一个使用分层窗口的解决方案,但我们希望确保它能在各种系统上运行(并且希望运行良好),并且我想查看是否有人有更好的想法,或者优化我在做什么的方法。我知道分层窗口需要win2000或更高版本,这很好,因为这已经是其他原因的要求。从一些基本测试看,它在Vista上看起来不错,但这还不能保证。

以下是我的工作:我有一个窗口,将其称为A,带有控件和文本以及包含该窗口的任何内容。我将窗口B作为窗口A的子窗口,除了它具有WS_POPUP样式而不是WS_CHILD,因此它可以将自己定位在A的区域之外并且绘制在A的控件之上。窗口B也具有WS_EX_LAYERED样式,在初始化时,我使用ULW_ALPHA标志调用UpdateLayeredWindow,并使用带有alpha通道的32位位图调用源DC,以便使用alpha像素进行绘制。

窗口B的源DC中使用的位图几乎就是窗口边界周围的像素,我希望从窗口背景平滑地混合到完全透明。我会跳过整个两窗口的方法,只使用一个单独的窗口,除了当你使用UpdateLayeredWindow时,它是从一个保存在内存中的缓冲区中取代典型的WM_PAINT消息和所有这些,并试图获得互动的儿童控制(和孩子的窗户)很好地工作,听起来像是一个非常麻烦(甚至可能不适用于所有的事情)。

所以,它基本上是窗口A的所有子控件和任何,窗口B直接浮动在它的顶部,绘制一个很好的光滑边界。我通过移动窗口B来响应WM_MOVE消息等等,并且我禁用了窗口B,所以它永远不会获得焦点或输入(点击已经通过,因为它的一部分是不透明的,比如大多数的内部部分,已被排除在采摘之外)。

对于踢腿,这是件看起来像什么,以表明我的意思是更好一点。

所以,它的工作原理,但我不能肯定它是真正做到这一点的最好办法。我有两个问题:

  • 这个声音是否可以接受,或者有什么明显的可怕的吗?
  • 因为它目前的工作,它似乎是使用窗口的大小(它可以高达1024x768)的屏幕外缓冲区,即使它的像素很少有任何非零不透明数据 - 它会是值得把它分割成单独的边界块并将它们合成在一起的开销和额外的复杂性?
+0

Doug,如果你能分享这个代码,那将是非常好的。提前致谢。 – 2010-07-20 12:39:04

回答

2

我的产品使用分层窗口绘制附加到每个窗口的小选项卡。我使用分层窗口来获得平滑舍入而不会出现锯齿。到目前为止我遇到的唯一令人讨厌的问题是,一些OpenGL窗口在没有DWM的Windows XP和Vista上的分层窗口上涂鸦。它是一个低级别的问题,微软并没有太大的帮助。您可以通过打开Goog​​le Earth并在主渲染窗口上拖动应用程序来重现它,您的分层窗口将会消失。

+0

这应该没问题;这个应用程序基本上起到了一个更大的全屏DirectX应用程序的启动器的作用,所以它不太可能同时运行另一个3D /图形密集型程序(因为我们支持低端硬件,这会导致更糟糕的问题)。感谢您的警告! – 2009-04-28 17:39:59

3

我已经发现了一件事情:拥有单独的框架件可以呈现比拥有一个巨大的框架窗口显着更快,中间有一大片空白像素。我没有任何实际的数字,但仅仅通过两种方法的快速测试,当几个窗口与全帧窗口相互重叠时,有明显的延迟,但是当它们的帧被切割成更小的组件时,它更加快速。无论使用自己的设备上下文具有多个分层窗口的开销是多少,并且具有大量像素(空白或不是!)仍会产生更多的负载。

1
  1. 不要忘记下RDP和虚拟机(Hyper-V的& VMWare的)来测试
  2. 试几种GFX卡和上网本和笔记本电脑(如适用)。