2009-09-01 75 views
20

我有給定窗口的句柄。我如何枚舉它的子窗口?如何根據HWND獲得窗口的子窗口?

+1

一般。我可以獲得我想列舉的窗口的HWND。 – 2009-09-01 16:12:02

+0

非常好 - 我已經更新了您的問題,以便清楚說明。 – Shog9 2009-09-01 16:25:30

+1

假設你瞭解spy ++。使用這些東西的有用工具。 – David 2009-09-01 17:21:11

回答

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 2011-10-07 14:47:14

+1

Epu,如果沒有主窗口,那麼進程將不會有窗口句柄來獲取(即Process.MainWindowHandle == IntPtr.Zero)。 – 2011-10-07 21:31:03

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 2015-05-28 07:04:26

+0

@jai這是一個Windows庫,它已經存在並在您的機器中註冊。該代碼應該無需額外的參考。 – 2015-05-28 15:27:45

+0

謝謝@ caffe ....但實際上,如果我使用user32.dll,應用程序要求某種權限...在哪裏我可以不能運行該應用程序...我該如何解決... – jai 2015-05-29 06:10:51