2009-11-13 83 views
1

如何获取没有标题的窗口的句柄?有没有办法枚举桌面上的所有窗口,并筛选没有标题的窗口(在我的情况下,只有一个)并获取它的句柄。或者通过指定其他属性,如窗口一个特定的按钮或列表框等等获取没有标题的窗口的句柄..(C#)

+0

任何阻止你传递一个空字符串转化FindWindow函数? – Joey 2009-11-13 14:25:35

+3

旁注:你不能认为你的窗口是唯一没有标题的窗口。 – 2009-11-13 14:43:12

回答

1

这应做到:

... 
    using System.Runtime.InteropServices; 
    using System.Diagnostics; 

    ... 

public class foo() 
{ 
    ... 

    [DllImport ("user32")] 
    internal static extern int GetWindowText (int hWnd, String text, int nMaxCount); 

    [DllImport ("user32.dll")] 
    public static extern int GetWindowTextLength (int hWnd); 

    [DllImport ("user32.dll")] 
    public static extern int FindWindow (String text, String class_name); 

    [DllImport ("user32.dll")] 
    public static extern int FindWindowEx (int parent, int start, String class_name); 

    [DllImport ("user32.dll")] 
    public static extern int GetWindow (int parent, uint cmd); 

    public List<int> FindTitlelessWindows() 
    { 
     List<int> titleless = new List<int>(); 

     Process [] procs = Process.GetProcesses(); 
     IntPtr hWnd; 

     foreach (Process proc in procs) 
     { 
      hWnd = proc.MainWindowHandle; 
      if (hWnd != IntPtr.Zero) 
      { 
       TraverseHierarchy (hWnd.ToInt32(), 0, titleless); 

      } 
     } 

     foreach (int i in titleless) 
     { 
      System.Console.WriteLine (i); 
     } 

     return titleless; 
    } 

    public void TraverseHierarchy (int parent, int child, List<int> titleless) 
    { 
     String text = ""; 
     GetWindowText (parent, text, GetWindowTextLength (parent)); 
     if (String.IsNullOrEmpty (text)) 
     { 
      titleless.Add (parent); 
     } 

     TraverseChildern (parent, titleless); 
     TraversePeers (parent, child, titleless); 

    } 

    public void TraverseChildern(int handle, List<int> titleless) 
    { 
     // First traverse child windows 
     const uint GW_CHILD = 0x05; 
     int child = GetWindow (handle, GW_CHILD); 
     if (0 != child) 
     { 
      TraverseHierarchy (child, 0, titleless); 

     } 
    } 

    public void TraversePeers(int parent, int start, List<int> titleless) 
    { 
     // Next traverse peers 
     int peer = FindWindowEx(parent, start, ""); 
     if (0 != peer) 
     { 
      TraverseHierarchy (parent, peer, titleless); 
     } 

    } 
} 
+0

如果顶层窗口足够,但也检查窗口是否是特定程序的一部分,你的: 'foreach(进程proc in procs) { hWnd = proc.MainWindowHandle; 如果(HWND = IntPtr.Zero && proc.MainWindowTitle == “” && proc.ProcessName.StartsWith( “我的进程名”)!) { titleless.Add(hWnd.ToInt32()); } }' – kjyv 2015-09-05 14:24:11

0

像这样的事情应该工作,没有测试

[DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)] 
internal static extern int GetWindowText(IntPtr hWnd, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpString, int nMaxCount); 

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
public static extern int GetWindowTextLength(IntPtr hWnd); 

.... 
Process[] procs = Process.GetProcesses(); 
IntPtr hWnd; 
foreach(Process proc in procs) 
{ 
    hWnd = proc.MainWindowHandle; 
    if (hWnd != IntPtr.Zero) 
    { 
     int length = GetWindowTextLength(hWnd); 
     StringBuilder sb = new StringBuilder(length + 1); 
     GetWindowText(hWnd, sb, length); 
     if (String.IsNullOrEmpty(sb.ToString()) 
     { 
      // we have a window with no title! 
     } 
    } 
} 
+0

这只会找到没有标题的顶级窗口。你仍然需要遍历所有的孩子窗口和同龄人。 – 2009-11-13 15:41:48

+0

你假设OP想包括子窗口(可能不包括)。 OTOH(正如你所暗示的)并不是每个顶层窗口都是一个进程的主窗口... – 2009-11-17 16:20:50

2

看看EnumChildWindows函数。

我认为,如果您将主窗口(即桌面)的指针传递给此函数,您将能够获得所有窗口及其子窗口的列表。

与FindWindow结合后,一旦找到预期的子控件,应该可以获取所需窗口的句柄。

0

Here你可以找到一个库来处理托管代码中的Windows API东西。
下载DLL并在你的项目中引用它,并从那里很容易 得到你想要的任何窗口的任何信息;

void ForAllSystemWindows() 
     { 
      foreach (SystemWindow window in SystemWindow.AllToplevelWindows) 
      { 
       if (window.Title == string.Empty) 
       { 
        //Found window without title 

        //Get window handle 
        IntPtr windowhandle = window.HWnd; 

        //Do other stuff .. 
       } 
      } 
     }