1

I have an application that needs all the windows which are visible to the screen. If a window is hidden by other windows then we ignore that. If any part of the windows is visible to the screen then only we need those windows.

So is there any way to find only those windows which are Actually visible to the screen?

Thank you so much.

Platform: Windows

jaykr
  • 81
  • 7
  • Have you considered enumerating all the windows and building an occlusion map using their rectangles (via some kind of quad-tree method)? If a window becomes completely occluded, it can be removed from consideration. According to [this answer](https://stackoverflow.com/a/296014/1553090), enumeration follows the Z-order. – paddy Jan 19 '21 at 06:04
  • Enumerate the windows, and check `GetClipBox` of each window `DC`. See [Determining whether your window is covered](https://devblogs.microsoft.com/oldnewthing/20030902-00/?p=42693). – dxiv Jan 19 '21 at 06:10
  • @dxiv GetClipBox always returning NULLREGION even if the window is partially obscured. – jaykr Jan 19 '21 at 06:23
  • @jaykr `GetDC` works for the client area. If you mean the entire window including non-client areas, you can use `GetDCEx` with `DCX_WINDOW` instead. If it still doesn't work, make sure to check each step in the enumeration and clipbox code or, even better, [edit](https://stackoverflow.com/posts/65786181/edit) it into the question. – dxiv Jan 19 '21 at 06:30
  • A C# solution (not C++) but should be readily adaptable: https://stackoverflow.com/q/5445889/10871073 (The WinAPI calls are much the same.) – Adrian Mole Jan 19 '21 at 06:48
  • 1
    I suspect we are looking at a https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem Please explain a little about why you need to do what you are asking about. I think you might for example otherwise use a concept of updating parts of windows which do need updating, there are convenient mechanisms for that. So, why is reacting to a suitable event not an option for you? – Yunnosch Jan 19 '21 at 06:58
  • On (not so) recent version of Windows, the desktop is composed more dynamically. Windows can become transparent or semi transparent (which explain why many "old" API don't seem to work). The notion of "actual visibility" is very fuzzy. Visibility can change in real time. – Simon Mourier Jan 19 '21 at 07:52
  • @AdrianMole I have tried it but not getting results as expected may be I am doing something wrong. When I use GetWindowRect() of the second top window when the top window is restored size its getting its {0,0,0,0}. – jaykr Jan 20 '21 at 05:11

1 Answers1

1

EnumWindows to get all the top level windows

GetWindowRect - to get the screen coordinates of each window.

GetWindow - to compare z-orders so you can detect which window is occluded by another. You many not need this if you just rely on the behavior of EnumWindow to return handles in z-order priority.

GetDesktopWindow - combined with GetWindowRect, you can get the screen coordinates.

Between these four functions and some math to detect rectangle intersections, you can probably find all the top-level windows that aren't occluded by another window or are positioned off screen.

selbie
  • 100,020
  • 15
  • 103
  • 173
  • `GetWindowRect` started lying starting with Windows Vista. Something you're going to have to deal with. Also, all API calls that return coordinates are subject do DPI virtualization. This is at least worth noting. – IInspectable Jan 19 '21 at 10:11
  • 1
    It shouldn't matter what DPI awareness mode you are in. The coordinate system of all these APIs should match the DPI awareness of all the currently running process. It's only when you try to thunk between processes running different DPI awareness levels when you run into issues. – selbie Jan 19 '21 at 11:12