IsHwndVisible() for Win 10 compatibilty

Share your advanced PureBasic knowledge/code with the community.
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

IsHwndVisible() for Win 10 compatibilty

Post 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.
User avatar
RSBasic
Moderator
Moderator
Posts: 1218
Joined: Thu Dec 31, 2009 11:05 pm
Location: Gernsbach (Germany)
Contact:

Re: IsHwndVisible() for Win 10 compatibilty

Post by RSBasic »

Image
Image
Image
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: IsHwndVisible() for Win 10 compatibilty

Post 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.
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: IsHwndVisible() for Win 10 compatibilty

Post 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?
Little John
Addict
Addict
Posts: 4519
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: IsHwndVisible() for Win 10 compatibilty

Post 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)
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: IsHwndVisible() for Win 10 compatibilty

Post by BarryG »

Thanks, LJ!
Post Reply