2
votes

This is the entire code of my C# application, with a simple goal. I want to retrieve the open windows on the system, ordered by how they were recently opened, just like in the Alt-Tab list. The Alt-Tab list lists programs as they were last opened, so that pressing Alt-Tab and releasing only once will take you back to the last window you had opened. This code is for Windows 10. The code below does get the information I need, just not in the right order. Where should I look for the information I need?

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace GetOpenWindowName
{
    class Program
    {
        static void Main(string[] args)
        {
            Process[] processlist = Process.GetProcesses();

            foreach (Process process in processlist)
            {
                if (!String.IsNullOrEmpty(process.MainWindowTitle))
                {
                    Console.WriteLine("Process: {0} ID: {1} Window title: {2}", process.ProcessName, process.Id, process.MainWindowTitle);
                }
            }

            Console.ReadLine();
        }
    }
}
2
This information is not available. You have to monitor window activation yourself.IInspectable
@PaulF that might be very helpful, thank you.Sam Weaver
Related (from 2003) - What is the Alt+Tab order?stuartd
The Z-order does not necessarily reflect the activation order. A window with the WS_EX_TOPMOST extended window style will break the relationship between Z-order and activation history.IInspectable

2 Answers

3
votes

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.

2
votes

Implementing EnumWindows seems to return the windows in tab order

[DllImport("user32.dll")]
private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);

Here is a good explanation of how to use How can I use EnumWindows to find windows with a specific caption/title?