Question

J'ai la poignée pour une fenêtre donnée. Comment puis-je énumérer ses fenêtres enfant?

Était-ce utile?

La solution 3

J'ai trouvé la meilleure solution pour être Managed WindowsAPI. Il avait un contrôle CrossHair qui pourrait être utilisé pour sélectionner une fenêtre (ne fait pas partie de la question), et une méthode AllChildWindows pour obtenir toutes les fenêtres de l'enfant qui enveloppées probablement la fonction EnumChildWindows. Mieux vaut ne pas réinventer la roue.

Autres conseils

Ici vous une solution de travail:

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;
    }
}

Comment consommer:

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

Utilisation:

internal delegate int WindowEnumProc(IntPtr hwnd, IntPtr lparam);

[DllImport("user32.dll")]
internal static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam);

vous obtiendrez callbacks sur la fonction que vous passez.

Utilisez EnumChildWindows, avec p / Invoke. Voici un lien intéressant certains de ses comportements: https: // blogs .msdn.microsoft.com / oldnewthing / 20070116-04 /? p = 28393

Si vous ne connaissez pas la poignée de la fenêtre, mais seulement son titre, vous aurez besoin d'utiliser EnumWindows. http://pinvoke.net/default.aspx/user32/EnumWindows.html

Voici une alternative réussi à EnumWindows, mais vous aurez toujours besoin d'utiliser EnumChildWindows pour trouver la poignée de la fenêtre de l'enfant.

foreach (Process process in Process.GetProcesses())
{
   if (process.MainWindowTitle == "Title to find")
   {
      IntPtr handle = process.MainWindowHandle;

      // Use EnumChildWindows on handle ...
   }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top