【问题标题】:How to determine if any part of the window is visible to Screen?如何确定窗口的任何部分是否对屏幕可见?
【发布时间】:2021-01-19 05:56:20
【问题描述】:

我有一个应用程序需要所有对屏幕可见的窗口。 如果一个窗口被其他窗口隐藏,那么我们忽略它。如果窗口的任何部分对屏幕可见,那么只有我们需要这些窗口。

那么有没有办法只找到那些在屏幕上实际可见的窗口?

非常感谢。

平台:Windows

【问题讨论】:

  • 您是否考虑过枚举所有窗口并使用它们的矩形构建遮挡图(通过某种四叉树方法)?如果窗口完全被遮挡,则可以将其从考虑中移除。根据this answer,枚举遵循Z-order。
  • 枚举窗口,检查每个窗口DCGetClipBox。见Determining whether your window is covered
  • @dxiv GetClipBox 总是返回 NULLREGION,即使窗口被部分遮挡。
  • @jaykr GetDC 适用于客户区。如果您指的是包括非客户区在内的整个窗口,您可以使用 GetDCExDCX_WINDOW 来代替。如果它仍然不起作用,请确保检查枚举和剪贴箱代码中的每个步骤,或者更好的是,edit 将其放入问题中。
  • 我怀疑我们正在查看meta.stackexchange.com/questions/66377/what-is-the-xy-problem 请解释一下为什么您需要做您所询问的事情。例如,我认为您可能会使用更新确实需要更新的窗口部分的概念,为此有方便的机制。那么,为什么对合适的事件做出反应不是您的选择?

标签: c++ windows winapi


【解决方案1】:

EnumWindows 获取所有顶层窗口

GetWindowRect - 获取每个窗口的屏幕坐标。

GetWindow - 比较 z 顺序,以便检测哪个窗口被另一个窗口遮挡。如果您只依赖 EnumWindow 的行为以 z 顺序优先级返回句柄,那么您很多人都不需要这个。

GetDesktopWindow - 结合GetWindowRect,可以得到屏幕坐标。

在这四个函数和一些用于检测矩形交叉点的数学运算之间,您可能可以找到所有未被另一个窗口遮挡或位于屏幕外的顶级窗口。

【讨论】:

  • GetWindowRect 从 Windows Vista 开始撒谎。你将不得不处理的事情。此外,所有返回坐标的 API 调用都需要进行 DPI 虚拟化。这至少值得注意。
  • 不管你处于什么DPI感知模式。所有这些API的坐标系应该匹配所有当前正在运行的进程的DPI感知。只有当您遇到问题时,才尝试在运行不同 DPI 感知级别的进程之间切换。
猜你喜欢
  • 2011-06-08
  • 1970-01-01
  • 2010-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-09
  • 2022-10-14
  • 2017-09-16
相关资源
最近更新 更多