4

查看 Windows类提示窗口,我看到它在提示窗口的实际矩形之外tooltips绘制了阴影。

使用SpyXX - 我可以获得工具提示的窗口矩形和类样式:

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

您会注意到您看到的投影实际上位于正在绘制的窗口之外。我怎样才能在窗外画一个阴影,同时在窗外

注意阴影不是使用标准CS_DROPSHADOW类样式绘制的。我已经通过实验证实了这一点,并且还可以在SpyXX中查看窗口的类样式;它不使用CS_DROPSHADOW

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

那么我怎样才能在窗外画画呢?

注意:尝试在桌面上绘制 DC 已失效。来自 Greg Schechter 的重定向 GDI、DirectX 和 WPF 应用程序

在屏幕上绘图和读取 - Baaaad!

最后,由于我们在重定向主题,一个特别危险的做法是写入屏幕,或者通过使用 GetDC(NULL) 并写入,或者尝试做 XOR 橡皮筋线等。有两个写入屏幕不好的主要原因:

它很昂贵……写入屏幕本身并不昂贵,但它几乎总是伴随着从屏幕读取,因为在写入屏幕时通常会执行诸如 XOR 之类的读取-修改-写入操作。从显存表面读取非常昂贵,需要与 DWM 同步,并且会停止整个 GPU 管道以及 DWM 应用程序管道。
这是不可预测的……如果您以某种方式设法到达实际的主节点并对其进行写入,则无法预测您写入主节点的内容将在屏幕上保留多长时间。由于UCE不知道,它可能会在下一帧刷新时被清除,也可能会持续很长时间,这取决于屏幕上还需要更新什么。(无论如何,我们确实不允许直接写入主节点,正因为如此......如果您尝试访问 DirectDraw 主节点,例如,DWM 将关闭,直到访问应用程序退出)

4

3 回答 3

5

你不能以你描述的方式在窗外画画。

如果您右键单击桌面然后转到属性/外观/效果并取消选中“在菜单下显示阴影”......您将不再有阴影。

底线是这是窗口管理器的产品,而不是您的程序。

于 2010-02-09T21:58:06.143 回答
4

问:您如何在一个窗口之外绘制?A:在另一个窗口内绘图!

首先要注意的是工具提示类实际上确实使用了该CS_DROPSHADOW样式 - 但请注意,这是一个样式,而不是窗口样式,因此您必须查看Spy++ 属性对话框中的“类”选项卡才能找到它。你会看到tooltips_class32窗户确实有这个 - 以及其他一些。

但这只会引出下一个问题——它是如何工作的?好吧,Windows 似乎通过创建一个辅助 HWND 来绘制阴影来实现这一点 - 大概它正在创建另一个与它的阴影相同大小和形状的弹出窗口,用灰色填充它,将它直接放在主窗口下方,并设置它作为WS_EX_LAYERED窗口,以便阴影可以透明并使用 alpha 混合在边缘周围淡出。如果您想为自己的一个窗口添加不同类型的阴影效果,没有什么可以阻止您自己使用相同或相似的技术。

所以,长话短说:如果你想在你自己的窗口之外绘制,在你想要绘制的一般区域中创建一个辅助透明窗口,然后在那个辅助窗口上绘制。

--

现在,如果您尝试在 Spy++ 中找到这些辅助阴影窗口之一,您将找不到太多。与tooltip_class32寿命长且只是根据需要隐藏/显示自己的窗口不同,这些阴影窗口是一种更难以捉摸的生物:它们只会在需要时创建,因此您必须在有工具提示时刷新 Spy++ 或使用阴影的弹出菜单或其他窗口存在 - 这很棘手,因为一旦您移动鼠标切换到 Spy++,大多数工具提示和菜单就会消失。但事实证明,Spy++ 自己工具栏上的工具提示会一直存在:所以启动 Spy++,将鼠标悬停在工具栏中的某个项目上,然后点击F5在工具提示和阴影存在时刷新 HWND 树。现在向下滚动,您应该会看到树中的第三个和第四个可见 HWND 是工具提示本身,然后是一个SysShadow窗口。不幸的是,由于工具提示和阴影现在已经消失,如果您尝试获取该 HWND 的属性对话框,您将获得一个带有“无效窗口”消息的空白属性对话框。如果您真的想四处看看 SysShadow 是如何工作的,它本身使用什么样式等等,您可以创建一个目标应用程序,其中包含一个长期存在的弹出窗口,CS_DROPSHADOW您可以在闲暇时在 Spy++ 中进行探索。

(Finally, note that these shadows are a completely different thing than the shadows that you see when one app window is on top of another above another since Vista: this type of shadow is part of Aero Glass mode, and handled by the same Desktop Composition Manager that adds the glass titlebar effect, and it doesn't use or need helper windows to implement the shadows.)

于 2013-01-07T13:42:23.553 回答
1

如果该阴影与窗口管理器本身密切相关,我不会感到惊讶。毕竟,窗口管理器决定了哪个窗口可以绘制其自身的哪些部分以及何时可以绘制。如果可以控制窗口管理器所拥有的一切,我不认为绘制阴影是火箭科学。

于 2010-02-09T21:53:29.943 回答