简体   繁体   English

检测窗口何时与来自相同或不同进程的另一个窗口重叠

[英]Detect when window gets overlapped by another window from the same or different process

Background背景

We are running our application in XenDesktop mode and our window shows some real time information.我们在 XenDesktop 模式下运行我们的应用程序,我们的窗口显示了一些实时信息。 But if some other application is also launched in that XenDekstop and that application is overlapping our window then we want to stop rendering.但是,如果其他应用程序也在该 XenDekstop 中启动并且该应用程序与我们的窗口重叠,那么我们希望停止渲染。 And once its moved out of our window then we want to start rendering again.一旦它移出我们的窗口,我们就想再次开始渲染。 Unfortunately, right now these kind of notifications are not supported by Citrix.不幸的是,Citrix 目前不支持此类通知。

Question问题

How can we detect when a part or the whole of the application window has been overlapped by other windows, and also detect when that's no longer the case?我们如何检测应用程序窗口的一部分或整个何时与其他窗口重叠,以及何时不再是这种情况?

I found the WindowFromPoint family of functions when Googling, however, that is not practical for my purpose because I'd need to keep polling all co-ordinates that my window covers.我在谷歌搜索时发现了WindowFromPoint函数系列,但是,这对我的目的来说并不实用,因为我需要不断轮询我的窗口覆盖的所有坐标。

Bonus points: For a start, it's enough if I can just detect when such overlapping occurs.加分点:首先,如果我能检测到何时发生这种重叠就足够了。 However, if I can detect exactly which area(s) of my window is/are covered that would be great.但是,如果我能准确地检测到我的窗口的哪些区域被覆盖,那就太好了。

There is no such API function.没有这样的 API 函数。 And usually the it isn't needed.通常不需要它。 WM_PAINT cares for itself. WM_PAINT 关心自己。

If you get a WM_PAINT message you receive a region and a update rectangle of the area that needs a repaint.如果您收到 WM_PAINT 消息,您将收到一个区域和需要重新绘制的区域的更新矩形。 But it is a rectangle only, no complex region.但它只是一个矩形,没有复杂的区域。 Also there is a clipping region too.还有一个剪辑区域。

But it should be possible to calculate the region by yourself.但是应该可以自己计算区域。 If we are talking about a top level window.如果我们谈论的是顶级窗口。

  • Create a rectangular region that is consists of your window rect创建一个由您的窗口矩形组成的矩形区域
  • Walk all top level windows from back to front从后向前走所有顶层窗户
  • Ignore all windows until you find your top level window忽略所有窗口,直到找到顶级窗口
  • For each visible top level window create a rectangular region and XOR it with your current one.对于每个可见的顶级窗口,创建一个矩形区域并将其与您当前的区域进行异或。
  • Should be easy with GetWindow GW_HWNDNEXT使用GetWindow GW_HWNDNEXT应该很容易

The resulting region is what you are searching for.结果区域就是您要搜索的区域。

Again: There is no such function or message that determine, that is fired or can be executed to find such overlapping.再次:没有这样的函数或消息来确定、触发或可以执行以找到这种重叠。 There is no need for such an information.不需要这样的信息。 The system cares for itself with the appropriate WM_PAINT message.系统通过适当的 WM_PAINT 消息自行处理。 If an area is covered.如果一个区域被覆盖。 There is no need for an action.没有必要采取行动。 If an area is uncovered WM_PAINT gets fired.如果某个区域未被覆盖,则 WM_PAINT 被触发。

I think you should be able to get this kind of information when processing the WM_PAINT message, since normally the clipping region would be set accordingly.我认为您在处理WM_PAINT消息时应该能够获得此类信息,因为通常会相应地设置剪切区域。 Calls to the RectVisible() function should tell you, for any part of your window, whether it "should be painted" (and so, whether it was just uncovered).RectVisible()函数的调用应该告诉您,对于窗口的任何部分,它是否“应该被绘制”(以及它是否刚刚被覆盖)。

尽管这不是 OP 问题的解决方案,但我想指出的是,一旦重叠窗口显示了您窗口的一部分(并且如果您将窗口的更多区域拖回屏幕),您将在 WM_PAINT 之前收到 WM_ERASEBKGND 消息.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM