c# - ¿Cómo puedo obtener las ventanas hijas de una ventana dado su HWND?
windows winapi (5)
Tengo el mango para una ventana dada. ¿Cómo puedo enumerar sus ventanas secundarias?
Aquí hay una alternativa administrada a EnumWindows, pero igual necesitará usar EnumChildWindows para encontrar el manejador de la ventana secundaria.
foreach (Process process in Process.GetProcesses())
{
if (process.MainWindowTitle == "Title to find")
{
IntPtr handle = process.MainWindowHandle;
// Use EnumChildWindows on handle ...
}
}
He encontrado la mejor solución para ser administrado WindowsAPI . Tenía un control CrossHair que se podía usar para seleccionar una ventana (no parte de la pregunta), y un método AllChildWindows para obtener todas las ventanas secundarias que probablemente envolvían la función EnumChildWindows. Mejor no reinventar la rueda.
Use EnumChildWindows, con p / invoke. Aquí hay un enlace interesante sobre su comportamiento: https://blogs.msdn.microsoft.com/oldnewthing/20070116-04/?p=28393
Si no conoce el manejo de la ventana, pero solo su título, deberá usar EnumWindows. http://pinvoke.net/default.aspx/user32/EnumWindows.html
Utilizando:
internal delegate int WindowEnumProc(IntPtr hwnd, IntPtr lparam);
[DllImport("user32.dll")]
internal static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam);
recibirás devoluciones de llamada en la función que ingresas.
Here tienes una solución de trabajo:
public class WindowHandleInfo
{
private delegate bool EnumWindowProc(IntPtr hwnd, IntPtr lParam);
[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr lParam);
private IntPtr _MainHandle;
public WindowHandleInfo(IntPtr handle)
{
this._MainHandle = handle;
}
public List<IntPtr> GetAllChildHandles()
{
List<IntPtr> childHandles = new List<IntPtr>();
GCHandle gcChildhandlesList = GCHandle.Alloc(childHandles);
IntPtr pointerChildHandlesList = GCHandle.ToIntPtr(gcChildhandlesList);
try
{
EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
EnumChildWindows(this._MainHandle, childProc, pointerChildHandlesList);
}
finally
{
gcChildhandlesList.Free();
}
return childHandles;
}
private bool EnumWindow(IntPtr hWnd, IntPtr lParam)
{
GCHandle gcChildhandlesList = GCHandle.FromIntPtr(lParam);
if (gcChildhandlesList == null || gcChildhandlesList.Target == null)
{
return false;
}
List<IntPtr> childHandles = gcChildhandlesList.Target as List<IntPtr>;
childHandles.Add(hWnd);
return true;
}
}
Cómo consumirlo:
class Program
{
[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
static void Main(string[] args)
{
Process[] anotherApps = Process.GetProcessesByName("AnotherApp");
if (anotherApps.Length == 0) return;
if (anotherApps[0] != null)
{
var allChildWindows = new WindowHandleInfo(anotherApps[0].MainWindowHandle).GetAllChildHandles();
}
}
}