Page 1 of 1

IsHwndVisible() for Win 10 compatibilty

Posted: Mon Jun 03, 2019 3:38 am
by BarryG
Just discovered today that invisible Windows 10 UWP windows (like Calculator, Microsoft Store, Settings, Xbox, and such) can return non-zero with IsWindowVisible_(), which is obviously NOT the desired result. I did some research and came up with this procedure that will correctly return 0 if any window is invisible, 1 if it's visible, or -1 if not found or unable to be determined.

I purposely named it IsHwndVisible() so as not to clash with IsWindowVisible_() when searching/replacing your sources.

Code: Select all

Prototype DwmGetWindowAttribute_(hWnd,dwAttribute.l,*pvAttribute,cbAttribute.l)
Procedure IsHwndVisible(hWnd)
  vis=-1 ; Means hWnd not found or couldn't determine visibility status.
  c$=Space(999)
  GetClassName_(hWnd,c$,999)
  If c$<>"ApplicationFrameWindow" And c$<>"Windows.UI.Core.CoreWindow" ; Normal Win32 window.
    vis=IsWindowVisible_(hWnd)
    If vis<>0 : vis=1 : EndIf
  Else ; Windows 10 UWP window, which can return non-zero for IsWindowVisible_() despite not shown!
    Define DwmGetWindowAttribute_.DwmGetWindowAttribute_
    #DWMWA_CLOAKED=14
    DWMAPIDLL=OpenLibrary(#PB_Any,"DWMAPI.DLL")
    If DWMAPIDLL
      DwmGetWindowAttribute_=GetFunction(DWMAPIDLL,"DwmGetWindowAttribute")
      If DwmGetWindowAttribute_ And DwmGetWindowAttribute_(hWnd,#DWMWA_CLOAKED,@Cloaked,SizeOf(Cloaked))=#S_OK
        If Cloaked=0
          vis=1
        Else
          vis=0
        EndIf
      EndIf
      CloseLibrary(DWMAPIDLL)
    EndIf
  EndIf
  ProcedureReturn vis
EndProcedure

Debug IsHwndVisible(FindWindow_(0,"Untitled - Notepad")) ; Standard Win32 window.
Debug IsHwndVisible(FindWindow_(0,"Microsoft Store"))    ; Windows 10 UWP window.

Re: IsHwndVisible() for Win 10 compatibilty

Posted: Mon Jun 03, 2019 6:59 am
by RSBasic
Image

Re: IsHwndVisible() for Win 10 compatibilty

Posted: Mon Jun 03, 2019 7:05 am
by BarryG
Thanks RSBasic. :)

Here's one of the pages I found that led me to the solution:

https://social.msdn.microsoft.com/Forum ... is-visible

It's pretty shocking that IsWindowVisible_() can't be relied on anymore. Really bad move, Microsoft - this will break a LOT of window-management tools.

Re: IsHwndVisible() for Win 10 compatibilty

Posted: Thu Aug 22, 2019 11:27 am
by BarryG
BTW, does the Prototype command have to go inside the procedure in my code? Or is it okay to stay outside? Are prototypes global?

Re: IsHwndVisible() for Win 10 compatibilty

Posted: Thu Aug 22, 2019 4:09 pm
by Little John
Prototypes have a global scope, like e.g. structures:

Code: Select all

EnableExplicit

Procedure.d CalcAdd (value1.d, value2.d)
   ProcedureReturn value1 + value2
EndProcedure

Procedure.d CalcMul (value1.d, value2.d)
   ProcedureReturn value1 * value2
EndProcedure

Prototype.d ProtoCalc (value1.d, value2.d)


Procedure Main (value1.d, value2.d)
   Protected Calc.ProtoCalc
   
   Calc = @ CalcAdd()
   Debug Calc(value1, value2)
   
   Calc = @ CalcMul()
   Debug Calc(value1, value2)
EndProcedure


Main(2.5, 3.0)

Re: IsHwndVisible() for Win 10 compatibilty

Posted: Thu Aug 22, 2019 10:10 pm
by BarryG
Thanks, LJ!