Hi all,
Other methods of doing this have never quite worked 100% for me, but this seems to do the trick. I'd be interested in hearing if it gets it wrong for anyone (state the program if it does!). You need the debugger turned on, and please note that it won't list the Debug Output window since that's not open when it makes the list!
USAGE: Call GetTBarButtons () and iterate through the TBarButtons () list, which can show the window's title -- "TBarButtons ()\name" -- and window handle -- "TBarButtons ()\window".
Code: Select all
Structure TaskbarButton
name.s
window.l
EndStructure
Global NewList TBarButtons.TaskbarButton ()
; The rules for checking whether a button is shown on the Taskbar
; or not are listed at the bottom of this file...
; Note: one difference with Task Manager's output is that this lists
; Task Manager's Taskbar button -- Task Manager skips it!
; GAH! Frigging EditPad and its crazy not-hidden-but-invisible window! (Sorted?)
; Windows 10 fix by BarryG:
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
Procedure ListTaskbarButtons (window, lparam)
If IsHwndVisible (window)
flags = GetWindowLong_ (window, #GWL_EXSTYLE)
If flags & #WS_EX_APPWINDOW
visible = #True
Else
If flags & #WS_EX_TOOLWINDOW
visible = #False
Else
; Neither style set...
If GetParent_ (window) = #Null
visible = #True
EndIf
EndIf
EndIf
; Not covered in rules, but EditPad 3.5.1 is listed as two buttons when only
; one is present, and this flag is in the child window (something to do with
; allowing input to reach child windows with this flag)...
If flags & #WS_EX_CONTROLPARENT
visible = #False
EndIf
If visible
title$ = Space (1024)
GetWindowText_ (window, @title$, 1024)
AddElement (TBarButtons ())
TBarButtons ()\name = title$
TBarButtons ()\window = window
EndIf
EndIf
ProcedureReturn #True
EndProcedure
Procedure GetTBarButtons ()
ClearList (TBarButtons ())
EnumWindows_ (@ListTaskBarButtons (), 0)
EndProcedure
; D E M O . . .
; Get list of visible buttons...
GetTBarButtons ()
; Iterate through list...
ResetList (TBarButtons ())
While NextElement (TBarButtons ())
Debug TBarButtons ()\name + " (handle: " + Str (TBarButtons ()\window) + ")"
Wend
; THE RULES FOR TASKBAR BUTTON VISIBILITY!
; From: http://www.microsoft.com/msj/1197/win321197.aspx
; The rules the taskbar uses to decide whether a button should be shown for a window are really quite simple,
; but are not well documented. When you create a window, the taskbar examines the window's extended style
; to see if either the WS_EX_APPWINDOW (defined as 0x00040000) or WS_EX_TOOLWINDOW (defined as
; 0x00000080) style is turned on. If WS_EX_APPWINDOW is turned on, the taskbar shows a button for the
; window, and if WS_EX_ TOOLWINDOW is turned on, the taskbar does not show a button for the window. You
; should never create a window that has both of these extended styles.
; You can create a window that doesn't have either of these styles. If a window has neither style, the taskbar
; decides to create a button if the window is unowned and does not create a button if the window is owned.
; One final note: before making any of the above tests, the taskbar first checks to see if a window has the
; standard WS_VISIBLE window style turned on. If this style bit is off, the window is hidden; the taskbar
; never shows a button for a hidden window. Only if the WS_VISIBLE style bit is on will the taskbar check
; the WS_EX_APPWINDOW, WS_ EX_TOOLWINDOW, and window ownership information.