2010-11-18 4 views
0

Я в основном пишу специализированный макро-плеер/рекордер в C#. Одна вещь, которую мне нужно сделать, это подождать всплывающее окно (что-то вроде диалогового окна «Сохранить как ...»), которое затем я могу выбрать, чтобы продолжить воспроизведение ввода макросов. В идеале, я хотел бы иметь возможность опроса для открытых окон и поиска по их названиям для соответствующего заголовка окна. Очевидно, я не могу использовать Processes.GetProcesses(), потому что диалог скорее всего не будет отображаться как новый процесс.C# Как подождать всплывающее окно и выбрать его для ввода

Где я могу найти открытые окна и их названия?

ответ

1

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

public class ProcessWindows 
{ 
    List<Window> visibleWindows = new List<Window>(); 
    List<IntPtr> allWindows = new List<IntPtr>(); 

    /// <summary> 
    /// Contains information about visible windows. 
    /// </summary> 
    public struct Window 
    { 
     public IntPtr Handle { get; set; } 
     public string Title { get; set; } 
    } 

    [DllImport("user32.dll")] 
    static extern int EnumWindows(EnumWindowsCallback lpEnumFunc, int lParam); 

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

    [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 
    private static extern void GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); 

    delegate bool EnumWindowsCallback(IntPtr hwnd, int lParam); 

    public ProcessWindows() 
    { 
     int returnValue = EnumWindows(Callback, 0); 
     if (returnValue == 0) 
     { 
      throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error(), "EnumWindows() failed"); 
     } 
    } 

    private bool Callback(IntPtr hwnd, int lParam) 
    { 
     const int WS_BORDER = 0x800000; 
     const int WS_VISIBLE = 0x10000000; 
     const int GWL_STYLE = (-16); 

     // You'll have to figure out which windows you want here... 
     int visibleWindow = WS_BORDER | WS_VISIBLE; 
     if ((GetWindowLong(hwnd, GWL_STYLE) & visibleWindow) == visibleWindow) 
     { 
      StringBuilder sb = new StringBuilder(100); 
      GetWindowText(hwnd, sb, sb.Capacity); 

      this.visibleWindows.Add(new Window() 
      { 
       Handle = hwnd, 
       Title = sb.ToString() 
      }); 
     } 

     return true; //continue enumeration 
    } 

    public ReadOnlyCollection<Window> GetVisibleWindows() 
    { 
     return this.visibleWindows.AsReadOnly(); 
    } 
} 
} 
+0

Один комментарий, я не смог понять, что вы имели в виду под WindowTitle.GetText(). Я не знаю, какую библиотеку я не импортирую или чего не хватает. Вместо этого я использовал другую функцию user32, статический extern int GetWindowText (int hWnd, текст StringBuilder, int count); – ashurexm

+0

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

+0

Хорошо, исправлено. Обратите внимание на новый оператор pinvoke для GetWindowText и его вызов, где раньше использовался WindowTitle.GetText(). (Это, в основном, то, что вы сделали в любом случае, очевидно.) –

 Смежные вопросы

  • Нет связанных вопросов^_^