获取进程的所有窗口句柄
使用Microsoft Spy ++,我可以看到以下属于某个进程的窗口:
处理XYZ窗口句柄,以树forms显示,就像Spy ++一样,它给了我:
A B C D E F G H I J K
我可以得到进程,MainWindowHandle属性指向窗口F的句柄。如果我使用枚举子窗口我可以得到G到K的窗口句柄列表,但我无法弄清楚如何找到窗口A到D的句柄。如何枚举不是Process对象的MainWindowHandle指定的句柄的子窗口?
要枚举我正在使用win32调用:
[System.Runtime.InteropServices.DllImport(strUSER32DLL)] public static extern int EnumChildWindows(IntPtr hWnd, WindowCallBack pEnumWindowCallback, int iLParam);
将IntPtr.Zero
作为hWnd
传递给系统中的每个根窗口句柄。
然后,您可以通过调用GetWindowThreadProcessId
来检查Windows的所有者进程。
您可以使用EnumWindows
获取每个顶级窗口,然后根据GetWindowThreadProcessId
过滤结果。
对于每个仍在疑惑的人来说,这就是答案:
List GetRootWindowsOfProcess(int pid) { List rootWindows = GetChildWindows(IntPtr.Zero); List dsProcRootWindows = new List (); foreach (IntPtr hWnd in rootWindows) { uint lpdwProcessId; WindowsInterop.User32.GetWindowThreadProcessId(hWnd, out lpdwProcessId); if (lpdwProcessId == pid) dsProcRootWindows.Add(hWnd); } return dsProcRootWindows; } public static List GetChildWindows(IntPtr parent) { List result = new List (); GCHandle listHandle = GCHandle.Alloc(result); try { WindowsInterop.Win32Callback childProc = new WindowsInterop.Win32Callback(EnumWindow); WindowsInterop.User32.EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle)); } finally { if (listHandle.IsAllocated) listHandle.Free(); } return result; } private static bool EnumWindow(IntPtr handle, IntPtr pointer) { GCHandle gch = GCHandle.FromIntPtr(pointer); List list = gch.Target as List ; if (list == null) { throw new InvalidCastException("GCHandle Target could not be cast as List "); } list.Add(handle); // You can modify this to check to see if you want to cancel the operation, then return a null here return true; }
对于WindowsInterop:
public delegate bool Win32Callback(IntPtr hwnd, IntPtr lParam);
对于WindowsInterop.User32:
[DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); [DllImport("user32.Dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam);
现在可以通过GetChildWindows获取GetRootWindowsOfProcess和子节点的每个根窗口。