2009-11-13 82 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 .. 
       } 
      } 
     }