winapi - 如何正确使用 LayeredWindows [英] winapi - How to use LayeredWindows properly

查看:26
本文介绍了winapi - 如何正确使用 LayeredWindows的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am haveing trouble understanding the concept of the UpdateLayaredWindow api, how it works and how to implement it. Say for example I want to override CFrameWnd and draw a custom, alpha blended frame with UpdateLayeredWindow, as I understand it, the only way to draw child controls is to either: Blend them to the frame's Bitmap buffer (Created with CreateCompatibleBitmap) and redraw the whole frame, or create another window that sits ontop of the layered frame and draws child controls regularly (which defeats the whole idea of layered windows, because the window region wouldn't update anyway).

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

If I use the first method, the whole frame is redrawn - surely this is inpractical for a large application..? Or is it that the frame is constantly updated anyway so modifying the bitmap buffer wouldn't cause extra redrawing.

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

An example of a window similar to what I would like to achieve is the Skype notification box/incoming call box. A translucent frame/window with child contorls sitting ontop, that you can move around the screen.

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

In a practical, commercial world, how do I do it? Please don't refer me to the documentation, I know what it says; I need someone to explain practical methods of the infrastructure I should use to implement this.

谢谢.

推荐答案

目前还不清楚分层窗口的哪些方面给您带来了问题,我将只讨论它们是如何实现的,并从中解释它们的局限性.

It is very unclear exactly what aspect of layered windows gives you a problem, I'll just noodle on about how they are implemented and explaining their limitations from that.

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

Layered windows are implemented by using a hardware feature of the video adapter called "layers". The adapter has the basic ability to combine the pixels from distinct chunks of video memory, mixing them before sending them to the monitor. Obvious examples of that are the mouse cursor, it gets super-imposed on the pixels of the desktop frame buffer so it doesn't take a lot of effort to animate it when you move the mouse. Or the overlay used to display a video, the video stream decoder writes the video pixels directly to a separate frame buffer. Or the shadow cast by the frame of a toplevel window on top of the windows behind it.

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

The video adapter allows a few simple logical operations on the two pixel values when combining their values. The first one is an obvious one, the mixing operation that lets some of the pixel value overlap the background pixel. That effect provides opacity, you can see the background partially behind the window.

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

The second one is color-keying, the kind of effect you see used when the weather man on TV stands in front of a weather map. He actually stands in front of a green screen, the camera mixing panel filters out the green and replaces it with the pixels from the weather map. That effect provides pure transparency.

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

You see this back in the arguments passed to UpdateLayeredWindow(), the function you must call in your code to setup the layered window. The dwFlags argument select the basic operations supported by the video hardware, ULW_ALPHA flag enables the opacity effect, the ULW_COLORKEY flag enables the transparency effect. The transparency effect requires the color key, that's specified with the crKey argument value. The opacity effect is controlled with the pblend argument. This one is built for future expansion, one that hasn't happened yet. The only interesting field in the BLENDFUNCTION struct is SourceConstantAlpha, it controls the amount of opacity.

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

So a basic effect available for a layered window is opacity, overlapping the background windows and leaving the partially visible. One restriction to that the entire window is partially opaque, including the border and the title bar. That doesn't look good, you typically want to create a borderless window and take on the burden of creating your own window frame. Requires a bunch of code btw.

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

And a basic effect is transparency, completely hiding parts of a window. You often want to combine the two effects and that requires two layered windows. One that provides the partial opacity, another on top and owned by the bottom one that displays the parts of the window that are opaque, like the controls. Using the color key to make its background transparent and make the the bottom window visible.

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

Beyond this, another important feature for custom windows is enabled by SetWindowRgn(). It lets you give the window a shape other than a rectangle. Again it is important to omit the border and title bar, they don't work on a shaped window. The programming effort is to combine these features in a tasteful way that isn't too grossly different from the look-and-feel of windows created by other applications and write the code that paints the replacement window parts and still makes the window functional like a regular window. Things like resizing and moving the window for example, you typically do so by custom handling the WM_NCHITTEST message.

这篇关于winapi - 如何正确使用 LayeredWindows的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆