I am working on enumerating all *visible top-level windows* on Windows 11 using
**pywin32 (`win32gui`) + UI Automation (UIA)**.
### Expected behaviour
Using:
```python
def callback(hwnd, _):
if win32gui.IsWindowVisible(hwnd) and
vdm.is_window_on_current_desktop(hwnd):
handles.add(hwnd)
win32gui.EnumWindows(callback, None)
```
Note: vdm is Virtual Desktop Manager in Windows 11/10 (used to filter apps
belong to current desktop)
Win32Gui doesn't filter it out based on the current desktop
I expect to receive **all visible windows**, including:
* Taskbar (IsVisible=True)
* Start Menu (if open)(IsVisible=False)
* Search Window (if open)(IsVisible=False)
### Actual behavior
The above method successfully detects **all standard applications**, but
**fails to detect**:
* Start Menu (if it was open)
* Search window (it it was open)
These windows are **clearly visible in UI Automation**, but **do not appear as
normal top-level windows** when using:
```python
win32gui.EnumWindows
```
---
## Current workaround (not ideal)
I currently have to **hard-code window class names**, which I want to avoid:
```python
if desktop_hwnd := win32gui.FindWindow('Progman', None):
handles.add(desktop_hwnd)
if taskbar_hwnd := win32gui.FindWindow('Shell_TrayWnd', None):
handles.add(taskbar_hwnd)
if secondary_taskbar_hwnd := win32gui.FindWindow('Shell_SecondaryTrayWnd',
None):
handles.add(secondary_taskbar_hwnd)
if start_hwnd := win32gui.FindWindow('Windows.UI.Core.CoreWindow', 'Start'):
handles.add(start_hwnd)
if search_hwnd := win32gui.FindWindow('Windows.UI.Core.CoreWindow', 'Search'):
handles.add(search_hwnd)
```
This is **fragile**, version-dependent, and breaks across OS updates.
---
## UI Automation observation
Using UI Automation:
```python
root = uia.GetRootControl()
children = root.GetChildren()
```
The Start and Search windows **do appear here**, but:
* Accessing `root.GetChildren()` is **very expensive**
* This significantly hurts performance
* I want to avoid full UIA tree traversal
---
## EnumChildWindows observation
```python
win32gui.EnumChildWindows(desktop_hwnd, callback, None)
```
Here I **can see Start and Search**, but:
* Their **children cannot be accessed**
* Some of their **window handles resolve to `0`**
* Moving up the parent chain fails to reach a usable Start Menu HWND
---
## Foreground window anomaly
Another strange behavior:
```python
win32gui.GetForegroundWindow()
```
Even when **Start Menu is open**, this returns the **Search window**, not the
Start Menu.
Additionally:
* The Start Menu contains the Search window as a child
* But calling `GetParent()` or walking upward gives `0`
* The actual Start Menu HWND is not reachable
---
## Suspected Cause
It appears that on **Windows 11**, Start Menu, Search, and Taskbar:
* Are **not normal Win32 top-level windows**
* Are implemented as **UWP / XAML / CoreWindow / shell surfaces**
* Therefore **do not participate in normal HWND enumeration**
---
## Question
Is there a **reliable, generic way** (without hardcoding class names and
without expensive UIA to get_children of the root node) to:
* Enumerate **all visible shell windows**, including:
* Taskbar
* Start Menu
* Search
Preferably using **Win32 APIs / pywin32**?
Or is **UI Automation traversal the only supported way** on Windows 11?
---
## Environment
* OS: **Windows 11 25H2**
* Build: **26200.7462**
* Python: 3.14
* pywin32: latest
* UI Automation: uiautomation / comtypes
_______________________________________________
python-win32 mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-win32.python.org
Member address: [email protected]