EnumWindows no longer finds Metro/Modern UI windows: a workaround

In the final release of Windows 8, the EnumWindows function no longer lists Metro/Modern UI windows:

Note For Windows 8 and later, EnumWindows enumerates only top-level windows of desktop apps.

This change was made some time around the consumer preview release. I’m not sure why Microsoft did this, but there is a simple workaround. Instead of calling EnumWindows, call this function:

VOID EnumWindowsWithMetro(
    __in WNDENUMPROC lpEnumFunc,
    __in LPARAM lParam
    )
{
    HWND childWindow = NULL;
    ULONG i = 0;

    while (i < 1000 && (childWindow = FindWindowEx(NULL, childWindow, NULL, NULL)))
    {
        if (!lpEnumFunc(childWindow, lParam))
            return;

        i++;
    }
}

The reason this works is that FindWindowEx, unlike EnumWindows, does not ignore Metro windows. We just call FindWindowEx in a loop to keep retrieving the next window in the list until there are no more. Note the i < 1000 condition, which is there to prevent infinite loops (highly unlikely but possible, to my knowledge).

6 responses

  1. Thanks, How can I use it in C# ? In windows 7 I used EnumWindows win = new EnumWindows(), and after method GetWindows();
    Thank you

Leave a Reply