2009-11-13 3 views
1

Как мы можем получить дескриптор окна, у которого нет названия? Есть ли способ перечислить все окна на рабочем столе и фильтровать окно, в котором нет заголовка (в моем случае есть только один) и получить его дескриптор .. или указав другие атрибуты, такие как окно, которое имеет специальная кнопка или ListBox и т.д. ...Получить ручку окна, которое не имеет названия .. (C#)

+0

Все, что мешает вам передать пустую строку в FindWindow? – Joey

+3

Sidenote: Вы не можете предположить, что ваше окно является единственным, у которого нет названия. –

ответ

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 (Process proc in procs) { hWnd = proc.MainWindowHandle; если (HWND = IntPtr.Zero && proc.MainWindowTitle == "" && proc.ProcessName.StartsWith ("мое имя процесса")!) { titleless.Add (hWnd.ToInt32()); } } ' – kjyv

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

Это будет только поиск окон верхнего уровня без заголовка. Вам все равно нужно пройти все дочерние окна и сверстники. –

+0

Вы предполагаете, что OP хочет включить дочерние окна (возможно, нет). OTOH (как вы подразумеваете) не каждое окно верхнего уровня является MainWindow процесса ... –

0

http://msdn.microsoft.com/en-us/library/ms633558(VS.85).aspx

WindowFromPoint возвращает дескриптор, или нуль, если окно не находится под курсором. Может ли это быть использовано или вы пытаетесь автоматизировать процесс?

2

Посмотрите на функцию EnumChildWindows.

Я думаю, что если вы передадите эту функцию в указатель главного окна (например, рабочий стол), вы сможете получить список всех окон и их дочерних окон.

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

0

Here вы можете найти библиотеку, которая будет обрабатывать файлы API Windows в управляемом коде.
Скачайте 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 .. 
       } 
      } 
     } 
Смежные вопросы