如何获得在Windows中的Z顺序?

我正在创build一个应用程序,与每个正在运行的应用程序交互 现在,我需要一个获取窗口z顺序的方法。 例如,如果Firefox和记事本正在运行,我需要知道哪一个在前面。

有任何想法吗? 除了为每个应用程序的主窗口执行此操作外,还需要为其子窗口和姐妹窗口(属于同一进程的窗口)执行此操作。

您可以使用GetTopWindow函数search父窗口的所有子窗口,并返回一个句柄到z顺序最高的子窗口。 GetNextWindow函数按z顺序检索下一个或上一个窗口的句柄。

GetTopWindow: http : //msdn.microsoft.com/en-us/library/ms633514( VS.85) .aspx
GetNextWindow: http : //msdn.microsoft.com/en-us/library/ms633509( VS.85) .aspx

尼斯和简洁:

int GetZOrder(IntPtr hWnd) { var z = 0; for (var h = hWnd; h != IntPtr.Zero; h = GetWindow(h, GW.HWNDPREV)) z++; return z; } 

如果你需要更多的可靠性:

 /// <summary> /// Gets the z-order for one or more windows atomically with respect to each other. In Windows, smaller z-order is higher. If the window is not top level, the z order is returned as -1. /// </summary> int[] GetZOrder(params IntPtr[] hWnds) { var z = new int[hWnds.Length]; for (var i = 0; i < hWnds.Length; i++) z[i] = -1; var index = 0; var numRemaining = hWnds.Length; EnumWindows((wnd, param) => { var searchIndex = Array.IndexOf(hWnds, wnd); if (searchIndex != -1) { z[searchIndex] = index; numRemaining--; if (numRemaining == 0) return false; } index++; return true; }, IntPtr.Zero); return z; } 

(根据GetWindow的注释部分, EnumChildWindows比在一个循环中调用GetWindow更安全,因为你的GetWindow循环对于外部变化来说不是primefaces的。根据EnumChildWindows的Parameters部分,用一个空的父对象调用相当于EnumWindows 。)

然后,而不是单独调用EnumWindows为每个窗口,这也将不是primefaces和安全的并发更改,您发送每个窗口,你想比较一个PARAMS数组,使他们的Z – 订单都可以同时检索。

  // Find z-order for window. Process[] procs = Process.GetProcessesByName("notepad"); Process top = null; int topz = int.MaxValue; foreach (Process p in procs) { IntPtr handle = p.MainWindowHandle; int z = 0; do { z++; handle = GetWindow(handle, 3); } while(handle != IntPtr.Zero); if (z < topz) { top = p; topz = z; } } if(top != null) Debug.WriteLine(top.MainWindowTitle); 

这里是我的C#解决scheme:该函数返回给定的HWND的兄弟姐妹之间的zIndex,从最低zOrder 0开始。

 using System; using System.Runtime.InteropServices; namespace Win32 { public static class HwndHelper { [DllImport("user32.dll")] private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd); public static bool GetWindowZOrder(IntPtr hwnd, out int zOrder) { const uint GW_HWNDPREV = 3; const uint GW_HWNDLAST = 1; var lowestHwnd = GetWindow(hwnd, GW_HWNDLAST); var z = 0; var hwndTmp = lowestHwnd; while (hwndTmp != IntPtr.Zero) { if (hwnd == hwndTmp) { zOrder = z; return true; } hwndTmp = GetWindow(hwndTmp, GW_HWNDPREV); z++; } zOrder = int.MinValue; return false; } } }