2010-12-15 2 views
0

У меня есть приложение WPF, которое запускается из приложения из командной строки.user32.dll FindWindowEx, поиск элементов по имени класса в удаленном окне WPF

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

У меня есть рабочие модели с WPF и UIA Framework, WinForms и WinAPI, но, похоже, не могут заставить WinAPI и WPF играть хорошо.

Я использовал UISpy, WinSpy ++, Winspector, приложение проверки UIA, чтобы посмотреть элементы управления и т. Д., Но они, похоже, несут ту же информацию для WPF, что и WinForms.

Например, в приложении WinForms я вижу текстовое поле с именем класса «WindowsForms10.EDIT.app.0.33c0d9d», когда я просматриваю инструменты шпиона. Приложение UIA Automation Verify является единственным, кто признает, что элемент существует, и сообщает «TextBox».

Итак, мой вопрос заключается в том, как найти правильное имя класса для прохождения или есть более простой путь для поиска дочерних элементов?

// does not work in wpf 
IntPtr child = NativeMethods.FindWindowEx(parent, prevElement, "TextBox", null); 

// works in winforms 
IntPtr child = NativeMethods.FindWindowEx(parent, prevElement, "WindowsForms10.EDIT.app.0.33c0d9d", null); 

и вот импорт User32.dll я использую:

public class NativeMethods 
{ 
    public const int WM_SETTEXT = 0x000C; 
    public const int WM_GETTEXT = 0x000D; 
    public const uint CB_SHOWDROPDOWN = 0x014F; 
    public const uint CB_SETCURSEL = 0x014E; 
    public const int BN_CLICKED = 245; 
    public const uint WM_SYSCOMMAND = 0x0112; 
    public const int SC_CLOSE = 0xF060; 

    [DllImport("user32.dll", SetLastError = true)] 
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 

    [DllImport("user32.dll", SetLastError = true)] 
    public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle); 

    [DllImport("user32.dll", SetLastError = false)] 
    public static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem); 

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] 
    public static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, string lParam); 

    [DllImport("user32.dll")] 
    public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam); 

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] 
    public static extern int SendMessage(int hWnd, int Msg, int wParam, StringBuilder lParam); 


} 

ответ

3

Если вы хотите автоматизировать WPF, вы должны использовать UI Automation, а не «старую вещь прошлого "API окон :-).

Существует хорошее введение по автоматизации пользовательского интерфейса здесь: Bugslayer: GUI Control to Major Tom

Существует также интересный проект с открытым кодом под названием «White», который использует автоматизацию пользовательского интерфейса: White on codeplex. Есть несколько образцов там, если вы хотите копать.

+0

Я предпочитаю маршрут автоматизации пользовательского интерфейса. У меня это работает в WPF и UI Automation, а также WinForms и WinAPI. Часть этого упражнения определяла, можно ли сделать это (WPF с WinAPI). Из комментариев, приведенных ниже, это похоже на WinForms и предыдущие приложения, WinAPI - это опция, WPF и больше, чем использование UI Automation. Благодаря! – ajberry 2010-12-15 19:17:46