I have been working on filtering out windows out of EnumWindows from only including windows that are minimized or open to a list.
Code
def winEnumHandler(hwnd, ctx):
title = win32gui.GetWindowText(hwnd)
# Append HWND to list
if win32gui.IsWindowVisible(hwnd) and title != '':
app = ApplicationWindow(hwnd, title)
applications.append(app)
def scanApplication():
applications.clear()
win32gui.EnumWindows(winEnumHandler, None)
return applications
Expected/Actual
The problem with this code is that it does not correctly filter out some windows that are found through the EnumWindows
For example currently I have: Chrome ,IDE, and Discord open on my computer and only expect these to be in the applications list. However, I not only get those windows but background tasks such as: Calculator, Mail, Geforce Overlay, etc... These Background tasks are active but there is no window on the desktop nor are any of these minimzed. How would I be able to filter out background tasks out of EnumWindows
? Thanks for reading!
After doing some more research I ran into DWM, DWM offers a way you can look up attributes of windows to get more information out of them. One of these options is called cloak and does a great job at filtering out background processes from all windows. My code for this is below. I will also link the stackoverflow post that talks about DWMA in more detail.
def winEnumHandler(hwnd, ctx):
# DWM
isCloacked = ctypes.c_int(0)
ctypes.WinDLL("dwmapi").DwmGetWindowAttribute(hwnd, 14, ctypes.byref(isCloacked), ctypes.sizeof(isCloacked))
# Variables
title = win32gui.GetWindowText(hwnd)
# Append HWND to list
if win32gui.IsWindowVisible(hwnd) and title != '' and isCloacked.value == 0:
app = ApplicationWindow(hwnd, title)
applications.append(app)
DWM Filtering: Here
Following more from that link this final solution showed all the real windows:
class TITLEBARINFO(ctypes.Structure):
_fields_ = [("cbSize", ctypes.wintypes.DWORD), ("rcTitleBar", ctypes.wintypes.RECT),
("rgstate", ctypes.wintypes.DWORD * 6)]
def winEnumHandler(hwnd, ctx):
# Title Info Initialization
title_info = TITLEBARINFO()
title_info.cbSize = ctypes.sizeof(title_info)
ctypes.windll.user32.GetTitleBarInfo(hwnd, ctypes.byref(title_info))
# DWM Cloaked Check
isCloaked = ctypes.c_int(0)
ctypes.WinDLL("dwmapi").DwmGetWindowAttribute(hwnd, 14, ctypes.byref(isCloaked), ctypes.sizeof(isCloaked))
# Variables
title = wg.GetWindowText(hwnd)
# Append HWND to list
if wg.IsWindowVisible(hwnd) and title != '' and isCloaked.value == 0:
if not (title_info.rgstate[0] & wc.STATE_SYSTEM_INVISIBLE):
app = ApplicationWindow(hwnd, title)
applications.append(app)
Any simplifications please let me know! Thanks!