You'll need the following declarations:
Option Explicit Private Type Rect Left As Long Top As Long Right As Long Bottom As Long End Type Private Declare Function FindWindow Lib "User32" Alias "FindWindowA" (ByVal Class As String, ByVal Window As String) As Long Private Declare Function ChildWindowFromPointEx Lib "User32" (ByVal Parent As Long, ByVal X As Long, ByVal Y As Long, ByVal Flags As Long) As Long Private Declare Function GetDC Lib "User32" (ByVal hWnd As Long) As Long Private Declare Function GetClipBox Lib "GDI32" (ByVal hWnd As Long, Rect As Rect) As Long Private Declare Function GetClientRect Lib "User32" (ByVal hWnd As Long, Rect As Rect) As Long Private Declare Function EqualRect Lib "User32" (A As Rect, B As Rect) As Long Private Declare Function ReleaseDC Lib "User32" (ByVal hWnd As Long, ByVal hDC As Long) As Long Private Const NullRegion = 1, SimpleRegion = 2, ComplexRegion = 3
In the procedure where you want to determine this, first you'll need to get the actual window. GetDesktopWindow doesn't return the right one, since the shell creates a child window that serves as the actual desktop, which in turn can have several others.
Dim Desktop As Long, DC As Long, Clip As Rect, Client As Rect, Child As Long Desktop = FindWindow("Progman", "Program Manager") Do Child = ChildWindowFromPointEx(Desktop, 0, 0, 1) Select Case Child Case Desktop, 0: Exit Do End Select Desktop = Child Loop
More complete code would check if the window at (0, 0) was actually the desktop-sized window we're looking for and not some small desktop widget that happens to be at that location. Now we need to check how much of it is visible. Raymond Chen tells us how:
DC = GetDC(Desktop) If DC Then Select Case GetClipBox(DC, Clip) Case NullRegion 'Fully covered, e.g. if a window is maximized. Case SimpleRegion GetClientRect hWnd, Client If EqualRect(Client, Clip) Then 'This shouldn't normally happen, since even in auto-hide mode the taskbar partially covers it. Else 'Rectangular area visible. End If Case ComplexRegion 'Complex area visible. Case Else 'This shouldn't happen - it signifies the function failed. End Select ReleaseDC Desktop, DC Else 'Handle failure of GetDC here. End If