Enumerate Windows Like Alt-Tab Does

Retrieve order of open windows as ordered in the Alt-Tab list?

So, this is the best that I was able to do, with the help of @PaulF, @stuartd, and @IInspectible.

The order of the windows in the Alt-Tab list is roughly the z-order of the windows. @IInspectible informs us that a window set to topmost will break this, but for the most part, z-order can be respected. So, we need to get the z-order of open windows.

First, we need to bring in the external function GetWindow, using these two lines:

[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetWindow(IntPtr hWnd, int nIndex);

Once that function exists, we can create this function to get the z-order:

public static int GetZOrder(Process p)
{
IntPtr hWnd = p.MainWindowHandle;
var z = 0;
// 3 is GetWindowType.GW_HWNDPREV
for (var h = hWnd; h != IntPtr.Zero; h = GetWindow(h, 3)) z++;
return z;
}

Key point: the three in the call to the GetWindow function is a flag:

/// <summary>
/// The retrieved handle identifies the window above the specified window in the Z order.
/// <para />
/// If the specified window is a topmost window, the handle identifies a topmost window.
/// If the specified window is a top-level window, the handle identifies a top-level window.
/// If the specified window is a child window, the handle identifies a sibling window.
/// </summary>
GW_HWNDPREV = 3,

These are the building blocks to finding the z-order of the windows from a process list, which is (for the most part) what the Alt-Tab order is.

Detect Alt-Tab/Task Switching/ForegroundStaging Window accurately

I found a working solution to the problem: additionally, filter by process path using GetWindowModuleFileNameW.

rough pseudocode:

if window.class() in [..] && GetWindowModuleFileNameW(window.hwnd) == "C:\Windows\explorer.exe" {
ignore()
}

Processes cannot fake their path, so this works.

Show a list of applications like alt-tab in Win7

You failure is, that you should walk only visible windows... read the blog again.

For each visible window, walk up its owner chain until you find
the root owner. Then walk back down the visible last active popup
chain until you find a visible window. If you're back to where you're
started, then put the window in the Alt+↹Tab list.

Your code walks over every window!

HWNDs of Alt+Tab Menu (In Order)

You need to use GetTopWindow/GetNextWindow to enumerate through the desktop's children in Z order, and then test the style to see if it's eligible to be in the alt+tab list. Something like:

HWND child = GetTopWindow(NULL);
LONG mask = WS_VISIBLE | WS_CAPTION;

while (child != NULL)
{
LONG style = GetWindowLong(child, GWL_STYLE);

if ((style & mask) == mask)
{
// do something with child.
}

child = GetNextWindow(child, GW_HWNDNEXT);
}


Related Topics



Leave a reply



Submit