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]

Reply via email to