1

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!

Timberghost_
  • 155
  • 4
  • 16
  • You can check [`GetWindowPlacement()`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowplacement) to see if it helps? – Rita Han Oct 29 '20 at 08:50
  • [`IsIconic()`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-isiconic?redirectedfrom=MSDN) determines whether the specified window is minimized (iconic). – Rita Han Oct 29 '20 at 09:44
  • Hello thanks for the reply, I have tried returning the values of these functions and it doesn't seem that either function stops returning background processes – Timberghost_ Oct 29 '20 at 18:12

1 Answers1

2

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!

Timberghost_
  • 155
  • 4
  • 16
  • Just remove the `title != ''` filter because some valid windows just happen to have an empty title like running stuff like cmd `start "" "python.exe"` ... And this code (https://github.com/Kalmat/PyWinCtl/blob/59dc14dd6a14d7cb520c9abc37c890004c7d05c1/src/pywinctl/_pywinctl_win.py) does your filtering so it was a pain in the ass discover the failure, thanks – Jose Velandia Mar 27 '23 at 22:25