2009-09-01 112 views
20

Tôi có tay cầm cho một cửa sổ cụ thể. Làm thế nào tôi có thể liệt kê các cửa sổ con của nó?Làm thế nào tôi có thể nhận được các cửa sổ con của một cửa sổ cho HWND của nó?

+1

Nói chung. Tôi có thể lấy HWND của cửa sổ mà tôi muốn liệt kê. –

+0

Tuyệt vời - tôi đã cập nhật câu hỏi của bạn để làm rõ điều này. – Shog9

+1

giả sử bạn biết về spy ++. Công cụ hữu ích để làm việc với công cụ này. – David

Trả lời

6

Tôi đã tìm thấy giải pháp tốt nhất là Managed WindowsAPI. Nó có một điều khiển CrossHair có thể được sử dụng để chọn một cửa sổ (không phải là một phần của câu hỏi), và một phương thức AllChildWindows để có được tất cả các cửa sổ con có khả năng bao bọc chức năng EnumChildWindows. Tốt hơn là không tái tạo lại bánh xe.

9

Sử dụng:.

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

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

bạn sẽ nhận được callbacks về chức năng bạn vượt qua trong

3

Đây là giải pháp thay thế được quản lý cho EnumWindows, nhưng bạn vẫn sẽ cần phải sử dụng EnumChildWindows để tìm tay cầm của cửa sổ con.

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

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

Tôi đang cố gắng làm điều này, nhưng không có cửa sổ chính cho quá trình này. – Epu

+1

Epu, nếu không có một cửa sổ chính thì quá trình sẽ không có một cửa sổ xử lý để có được (tức là Process.MainWindowHandle == IntPtr.Zero). –

15

Here bạn có một giải pháp làm việc:

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

Làm thế nào để tiêu thụ nó:

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

làm thế nào tôi có thể nhận user32.dll ?? – jai

+0

@jai Đó là thư viện Windows, đã có và đã đăng ký trong máy của bạn. Mã đó sẽ hoạt động mà không cần thêm tài liệu tham khảo. –

+0

nhờ @caffe .... Nhưng thực sự nếu tôi sử dụng user32.dll, ứng dụng yêu cầu một số loại quyền ... nơi tôi không thể chạy ứng dụng ... làm thế nào tôi có thể giải quyết được ... – jai

Các vấn đề liên quan