2009-09-01 2 views
20

У меня есть ручка для данного окна. Как я могу перечислить его дочерние окна?Как я могу получить дочерние окна окна, учитывая его HWND?

+1

В целом. Я могу получить HWND окна, из которого я хотел бы перечислить. –

+0

Отлично - я обновил ваш вопрос, чтобы все было ясно. – Shog9

+1

Предположим, вы знаете о spy ++. Полезный инструмент для работы с этим материалом. – David

ответ

6

Я нашел, что лучшим решением является Managed WindowsAPI. У него был элемент управления CrossHair, который можно было использовать для выбора окна (а не части вопроса) и метода AllChildWindows для получения всех дочерних окон, которые, вероятно, завернули функцию EnumChildWindows. Лучше не изобретать велосипед.

9

Использование:.

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

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

вы получите обратные вызовы на функции вы передаете в

3

Вот управляемая альтернатива EnumWindows, но вам все равно нужно будет использовать EnumChildWindows, чтобы найти дескриптор дочернего окна.

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

     // Use EnumChildWindows on handle ... 
    } 
} 
+0

Я пытаюсь сделать это, но нет главного окна для процесса. – Epu

+1

Epu, если нет главного окна, тогда процесс не будет иметь обработчик окна для получения (т. Е. Process.MainWindowHandle == IntPtr.Zero). –

15

Here у вас есть рабочее решение:

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

Как потребить его:

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

как я могу получить user32.dll ?? – jai

+0

@jai Это библиотека Windows, она уже присутствует и зарегистрирована на вашем компьютере. Этот код должен работать без необходимости дополнительных ссылок. –

+0

спасибо @caffe .... Но на самом деле, если я использую user32.dll, приложение запрашивает какое-то разрешение ... где я не могу запустить приложение ... как я могу это решить ... – jai

Смежные вопросы