0

我无法理解 UpdateLayaredWindow api 的概念、它的工作原理以及如何实现它。例如,我想覆盖 CFrameWnd 并使用 UpdateLayeredWindow 绘制一个自定义的 alpha 混合框架,据我所知,绘制子控件的唯一方法是:将它们混合到框架的位图缓冲区(使用 CreateCompatibleBitmap 创建)并重绘整个框架,或者创建另一个位于分层框架顶部并定期绘制子控件的窗口(这违背了分层窗口的整个想法,因为窗口区域无论如何都不会更新)。

如果我使用第一种方法,则重新绘制整个框架 - 这对于大型应用程序来说肯定是不切实际的......?还是帧总是不断更新,所以修改位图缓冲区不会导致额外的重绘。

类似于我想要实现的窗口的一个示例是 Skype 通知框/来电框。一个半透明的框架/窗口,顶部有子控件,您可以在屏幕上移动。

在实际的商业世界中,我该怎么做?请不要让我参考文档,我知道它在说什么;我需要有人解释我应该用来实现它的基础设施的实用方法。

谢谢。

4

1 回答 1

3

目前还不清楚分层窗口的哪个方面会给您带来问题,我将简要介绍它们是如何实现的,并从中解释它们的局限性。

分层窗口是通过使用称为“层”的视频适配器的硬件特性来实现的。适配器具有组合来自不同视频内存块的像素的基本能力,在将它们发送到监视器之前将它们混合。明显的例子是鼠标光标,它叠加在桌面帧缓冲区的像素上,因此当您移动鼠标时不需要花费太多精力来为其设置动画。或者用于显示视频的叠加层,视频流解码器将视频像素直接写入单独的帧缓冲区。或者由顶层窗口的框架投射在其后面的窗户之上的阴影。

视频适配器在组合它们的值时允许对两个像素值进行一些简单的逻辑操作。第一个很明显,混合操作让一些像素值与背景像素重叠。该效果提供opacity,您可以在窗口后面看到部分背景。

第二个是颜色键控,当电视上的气象员站在气象图前时,您会看到这种效果。他实际上站在一个绿色屏幕前,摄像机混合面板过滤掉绿色并用天气地图中的像素替换它。这种效果提供了纯粹的透明度

您可以在传递给 UpdateLayeredWindow() 的参数中看到这一点,您必须在代码中调用该函数来设置分层窗口。dwFlags 参数选择视频硬件支持的基本操作,ULW_ALPHA 标志启用不透明效果,ULW_COLORKEY 标志启用透明效果。透明效果需要使用 crKey 参数值指定的颜色键。不透明度效果由 pblend 参数控制。这是为未来的扩展而构建的,尚未发生。BLENDFUNCTION 结构中唯一有趣的字段是 SourceConstantAlpha,它控制不透明度的量。

因此,可用于分层窗口的基本效果是不透明度,与背景窗口重叠并保持部分可见。对整个窗口的一个限制是部分不透明,包括边框和标题栏。这看起来不太好,您通常希望创建一个无边框窗口并承担创建自己的窗口框架的负担。顺便说一句,需要一堆代码。

基本效果是透明度,完全隐藏窗口的一部分。您经常希望将这两种效果结合起来,这需要两个分层窗口。一个提供部分不透明度,另一个在顶部并由底部拥有,它显示不透明的窗口部分,如控件。使用颜色键使其背景透明并使底部窗口可见。

除此之外,自定义窗口的另一个重要功能是由 SetWindowRgn() 启用的。它可以让你给窗口一个矩形以外的形状。同样重要的是省略边框和标题栏,它们不适用于形状窗口。编程工作是以一种与其他应用程序创建的窗口的外观没有太大区别的雅致方式组合这些功能,并编写代码来绘制替换窗口部件并仍然使窗口功能像一个常规窗口。例如,调整窗口大小和移动窗口之类的事情,通常是通过自定义处理 WM_NCHITTEST 消息来实现的。

于 2012-05-04T13:10:39.533 回答