19

我通过添加WS_EX_LAYERED扩展样式创建了一个分层窗口:

wndClass.ExStyle = wndClass.ExStyle | WS_EX_LAYERED;

Windows 将使用黑色作为色度键颜色值。我将留下一个黑色的大边框以使问题变得明显:

替代文字


构建窗口后,我告诉它使用黑色作为色度键颜色

SetLayeredWindowAttributes(hwnd, 0x00000000, 255, LWA_COLORKEY);

现在弹出的分层窗口显示为部分透明:

替代文字


问题是最后一步。我想使用自 Windows XP 以来可用的CS_DROPSHADOW类样式来创建投影:

wndClass.Style = wndClass.Style | CS_DROPSHADOW;

出现了投影,但是阴影包围了原来的矩形窗口,并且没有考虑到分层窗口提供的窗口透明度:

有谁知道我在某个地方错过了什么神奇的选项,可以让投影尊重非矩形分层窗口?


出现此问题的另一个示例是当您不包含 6px 填充/边距时。Windows® 主题绘制的提示窗口是非矩形的。这会在窗口透明的地方留下一个小的可见间隙,但不会出现投影:

替代文字

正如您从 Internet Explorer 的提示中看到的那样,Microsoft 已设法使其工作:

替代文字


仔细查看 Windowstooltips类提示窗口。使用SpyXX - 我可以获得它的窗口矩形和类样式:

SpyXX 说:

Rectangle:     (440, 229)-(544, 249), 104x20
Restored Rect: (440, 229)-(544, 249), 104x20
Client Rect:   (0, 0)-(104, 20), 104x20

所以一切都指向窗口本身是 104x20 像素,在窗口本身之外有阴影。(这与 一致CS_DROPSHADOW。)

接下来我可以查看tooltips窗口类的样式:

Windows Styles:     94000001

    WS_POPUP        80000000
    WS_VISIBLE      10000000
    WS_CLIPSIBLINGS  4000000
    TTS_ALWAYSTIP          1

Extended Styles:    00080088

    WS_EX_LAYERED      80000
    WS_EX_TOOLWIN         80
    WS_EX_TOPMOST          8

有趣的是,它不使用CS_SAVEBITS( 0x800); 这对于小型、短暂的窗口很有用。

它也不使用CS_DROPSHADOW( 0x20000)。所以现在我想知道它是如何在自己的窗口之外绘制的?

注意:透明分层窗口被记录为区域的首选技术。

编辑: Windows 2000 出现了分层 Windows。CS_DropShadow 是随 XP 添加的。

4

3 回答 3

8

透明分层窗口被记录为区域的首选技术。

但是,CS_DROPSHADOW 确实要注意地区。如果您使用区域裁剪或以其他方式塑造您的窗口,则投影将跟随新的轮廓。

幸运的是,您可以使用带有分层窗口的区域,并通过将两者结合起来获得您正在寻找的效果。

顺便说一句:tooltips_class32确实使用 CS_DROPSHADOW - 您不会在窗口样式中看到它,因为它是类样式,而不是窗口样式。

于 2010-02-10T10:00:25.863 回答
2

为什么不使用 LWA_ALPHA 并将阴影构建到图像中?

针对您的评论进行编辑:

A) 不会阻止您仅将 alpha 通道 PNG 用于阴影。将 2 张图像拼凑在一起并用作一张图像。
B) 生成阴影并不难。在图像中,您发布了具有 3 个不同 alpha 值的黑色。
C)但它不起作用,不是吗?即是时候发挥创意了。
D)然后不要试图让 Windows 做一些它不会为你做的事情。
E) 完全不相关。分层窗口为您处理。

我强烈建议您了解有关分层窗口的更多信息,因为它们可以帮助您实现目标。

Edit2:你有位图。它相当容易扫描图像并找到哪些位将是彩色键控(通过自己识别黑色),然后将其修改为具有 0 的 alpha ,而其他所有内容的 alpha 为 255(不是:您可能必须转换将图像从较低颜色格式转换为 32 位图像,您可以通过创建新 DC 并复制图像来完成此操作)。这将为您提供与 LWA_ALPHA 和 LWA_COLORKEY 相同的效果。从那里很容易识别边缘的像素,颜色变为(R = 0,G = 0,B = 0,A = 0)。然后,您将第一个像素更改为 192 的 alpha,一个将其设为 128,将其下方的一个设为 64。您现在在图像下方有一个看起来像阴影的 alpha'd 渐变。您可以调整 alpha 以获得您想要的效果。

于 2010-02-08T19:35:05.727 回答
0

CS_DROPSHADOW仅适用于标准矩形窗。 WS_EX_LAYEREDwindows不支持一切。它们更像是一种低级的自助服务方法,可以准确地绘制您想要的内容。

要获得投影,您必须自己从图像中的 Alpha 通道生成投影。

于 2010-02-09T21:14:20.190 回答