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();
}
}
}
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.