winapi - 如何正确使用分层窗口

winapi - How to use LayeredWindows properly

本文关键字:分层 窗口 何正确 winapi      更新时间:2023-10-16

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

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

类似于我想要实现的窗口示例是Skype通知框/来电框。一个半透明的框架/窗户,上面有儿童框,你可以在屏幕上移动。

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

谢谢。

目前

还不清楚分层窗口的哪个方面会给你带来问题,我只是喋喋不休地介绍它们是如何实现的,并解释它们的局限性。

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

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

第二个是颜色键控,当你看到电视上的天气预报员站在天气图前时使用的那种效果。 他实际上站在绿屏前,摄像机混合面板过滤掉绿色,并将其替换为天气图中的像素。 这种效果提供了纯粹的透明度

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

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

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

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