我正在开发一个应用程序,该应用程序接受另一个应用程序的主窗口句柄,并收集有关该窗口状态的信息。我可以轻松地收集有关子窗口的信息,但我无法访问应用程序的其他打开窗口甚至菜单。是否有办法获取应用程序的所有窗口句柄?
Process.MainWindowHandle
所做的一样:使用 P/Invoke 调用 EnumWindows
函数,该函数调用系统中每个顶级窗口的回调方法。GetWindowThreadProcessId
,并将窗口的进程 id 与 Process.Id
进行比较;如果进程 id 匹配,则将该窗口句柄添加到列表中。首先,您需要获取应用程序主窗口的窗口句柄。
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
IntPtr hWnd = (IntPtr)FindWindow(windowName, null);
然后,您可以使用此句柄获取所有子窗口:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
private List<IntPtr> GetChildWindows(IntPtr parent)
{
List<IntPtr> result = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(result);
try
{
EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
}
finally
{
if (listHandle.IsAllocated)
listHandle.Free();
}
return result;
}
EnumWindowProc
是从哪里来的? - Matthieu Charbonnier public void GetWindowHandles()
{
List<IntPtr> windowHandles = new List<IntPtr>();
foreach (Process window in Process.GetProcesses())
{
window.Refresh();
if (window.MainWindowHandle != IntPtr.Zero)
{
windowHandles.Add(window.MainWindowHandle);
}
}
}
阅读这篇文章,了解为什么要调用refresh方法并检查指针是否为零。