Test if a Window or control is visible and not covered by other windows or controls.
Maybe useful to someone:
; Inspired by https://stackoverflow.com/questions/5445889/get-which-process-window-is-actually-visible-in-c-sharp
; GW_HWNDPREV always returned window "Default IDM" on my system, so I had to take a different approach
#include <GUIConstantsEx.au3>
#include <WinAPISysWin.au3>
#include <WinAPIGdi.au3>
#include <WindowsConstants.au3>
Local $hGui = GUICreate("_hWnd_IsVisible", 180, 180)
Local $c_label = GUICtrlCreateLabel("test-1", 30, 30, 100, 100)
Local $hWnd_label = GUICtrlGetHandle($c_label)
GUICtrlSetBkColor(-1, 0x00ff00)
GUICtrlCreateLabel("test-2", 50, 50, 100, 100)
GUICtrlSetBkColor(-1, 0x00ffff)
GUISetState(@SW_SHOW)
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ExitLoop
EndSwitch
ConsoleWrite(TimerInit() & @TAB & "Gui=" & _hWnd_IsVisible($hGui) & @CRLF)
Opt("WinSearchChildren", 1)
ConsoleWrite(TimerInit() & @TAB & "Control=" & _hWnd_IsVisible($hWnd_label, $hGui) & @CRLF)
Opt("WinSearchChildren", 0)
WEnd
Func _hWnd_IsVisible($hWnd, $hWnd_ParentGui = 0)
Local $tRect_hWnd = _WinAPI_GetWindowRect($hWnd)
Local $h_Rgn_hWnd = _WinAPI_CreateRectRgn(DllStructGetData($tRect_hWnd, 1), DllStructGetData($tRect_hWnd, 2), DllStructGetData($tRect_hWnd, 3), DllStructGetData($tRect_hWnd, 4))
Local $tRect_hWndPrev, $h_Rgn_hWndPrev
Local $aList = WinList()
For $i = 1 To $aList[0][0]
If $aList[$i][1] = $hWnd Then ExitLoop
If BitAND(WinGetState($aList[$i][1]), 2) And $aList[$i][1] <> $hWnd_ParentGui Then
$tRect_hWndPrev = _WinAPI_GetWindowRect($aList[$i][1])
$h_Rgn_hWndPrev = _WinAPI_CreateRectRgn(DllStructGetData($tRect_hWndPrev, 1), DllStructGetData($tRect_hWndPrev, 2), DllStructGetData($tRect_hWndPrev, 3), DllStructGetData($tRect_hWndPrev, 4))
_WinAPI_CombineRgn($h_Rgn_hWnd, $h_Rgn_hWnd, $h_Rgn_hWndPrev, $RGN_DIFF)
_WinAPI_DeleteObject($h_Rgn_hWndPrev)
EndIf
Next
Local $iRes = _WinAPI_GetRgnBox($h_Rgn_hWnd, $tRect_hWnd)
_WinAPI_DeleteObject($h_Rgn_hWnd)
Switch $iRes
Case 1 ; $NULLREGION
Return 0
Case 2 ; $SIMPLEREGION
Return 1
Case 3 ; $COMPLEXREGION
Return 1
Case Else ; 0 = Error
Return -1
EndSwitch
EndFunc ;==>_hWnd_IsVisible