Win32:如何在窗外画画?

时间:2010-02-09 21:39:50

标签: winapi dropshadow layered-windows ws-ex-layered

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

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

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

你会注意到你看到的投影在物理外面正在绘制的窗口。如何在我的窗户外面画一个阴影,同时在外面我的窗口?

注意The shadow is not drawn using the standard CS_DROPSHADOW class style.我已经通过实验确认了这一点,并且还可以在 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的Redirecting GDI, DirectX, and WPF applications

  

从屏幕绘图和阅读    - Baaaad!

     

最后,因为我们正在进行重定向   话题,一个特别危险   练习是写在屏幕上,   要么通过使用GetDC(NULL)   写信,或试图   做XOR橡皮筋线等   写作的两个重要原因   屏幕坏了:

     

这很贵...写信给   屏幕本身并不昂贵,但它   几乎总是伴随着   从屏幕上读取因为一个   通常会执行read-modify-write   写入时的XOR操作   屏幕。从视频中读取   记忆表面很贵,   需要与DWM同步,   并停止整个GPU管道,如   以及DWM应用程序管道   这是不可预测的...如果你以某种方式   设法到达实际的主要   并写信给它,可能没有   关于你多久的可预测性   写信给主要人员将保留   屏幕。由于UCE不知道   关于它,它可能会被清除   下一帧刷新,或者它可能会持续存在   很长一段时间,取决于   还有什么需要更新的   屏幕。 (我们真的不允许直接   无论如何写给小学,为   那个原因......如果你试着   访问DirectDraw主要,用于   例如,DWM将关闭,直到   访问应用程序退出)

3 个答案:

答案 0 :(得分:5)

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

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

一句话是,这是窗口管理器的产品,而不是您的程序。

答案 1 :(得分:3)

问:你怎么在一个窗口外画画?答:在另一个窗口内画画!

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

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

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

-

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

(最后请注意,这些阴影与自Vista之后一个应用程序窗口位于另一个应用程序窗口之上时所看到的阴影完全不同:此类阴影是Aero Glass模式的一部分,并由相同的Desktop Composition Manager添加了玻璃标题栏效果,并且它不使用或需要辅助窗口来实现阴影。)

答案 2 :(得分:1)

如果那个阴影与窗口管理器本身密切相关,我不会感到惊讶;毕竟窗口管理器决定什么窗口来绘制哪些部分本身, 时它可以做到。如果控制窗口管理者所拥有的所有内容,我不认为它是绘制阴影的火箭科学。