Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine window visibility in Vista

I want to determine if a certain window is visible to the user or hidden/occluded. In Windows XP I would use the GetClipBox() function and check for a NULLREGION or empty RECT return value. This worked perfectly fine, but on Windows Vista it does not work if another window is occluding the window. In this case, GetClipBox() is returning SIMPLEREGION with a non-empty RECT.

Does anybody know why this is not working on Vista or if there is another way to check if a window can be seen by the user?

like image 820
flashk Avatar asked Mar 01 '23 05:03

flashk


1 Answers

The simple reason GetClipBox() is not returning NULLREGION with DWM enabled is because you are not being clipped! The whole point of the DWM is each window (that isn't a child, like buttons or edit boxes) gets it's own buffer to draw to, so foreground windows can be moved around without having to fill in the windows behind them.

As a simple example, hover over your window entry in the task bar when it is in the background and see it being updated in the preview.

Also note that with glass edges, your window can be completely covered by other windows and still be visible! (You can't even test client area, because of extended glass, like Windows Media Player uses - resize it to as small as it will go and see it use glass for its entire area!) Of course, layered windows (from XP on) and custom window regions meant this could always be the case, but now it's the default.

Summary/TL;DR:

If you are doing heavy animation/fancy effects and want to reduce CPU usage when running under the DWM, probably the best you can do is detect when your application looses foreground and fallback to more CPU friendly updating (NOT no updating! If you get a WM_PAINT, and ignore it because you are in the background, you won't get one when you are activated!).

like image 119
Simon Buchan Avatar answered Apr 20 '23 04:04

Simon Buchan