Как получить доступ к элементам, которые UI Spy не видит, для автоматизации приложения win32 с помощью C#

Я делаю приложение формы окна С#, которое автоматизирует другое приложение win32, используя классы System.Windows.Automation.

Есть некоторые элементы, которые мне нужно прочитать или взаимодействовать, но UISpy не находит эти поля, он находит только панель родительского контейнера.

Например, этот блок кода ниже должен возвращать много кнопок панели инструментов, но не работает:

var mainWindow = AutomationElement.RootElement.FindChildByNamePart("Back Office Control");
var mainWindowChildren = mainWindow.FindAll(TreeScope.Children, Condition.TrueCondition);
var toolBarPanel = mainWindowChildren[1];
var toolBarItens = toolBarPanel.FindAll(TreeScope.Children, Condition.TrueCondition);

Есть другой способ сделать это?


person rcarubbi    schedule 08.01.2014    source источник


Ответы (2)


Как вы только что узнали, кнопки панели инструментов на самом деле не являются отдельными элементами управления в мире обмена сообщениями Windows. Это также относится к пунктам меню и некоторым другим элементам управления.

Чтобы вызвать клик с помощью сообщения windows, нужно отправить WM непосредственно на панель инструментов, а не на кнопку, например TB_PRESSBUTTON (http://msdn.microsoft.com/en-us/library/windows/desktop/bb787389(v=vs.85).aspx ).

Вы должны использовать функцию SendMessage WinAPI, предназначенную для панели инструментов (вы можете получить hWnd как обычно), с TB_PRESSBUTTON в качестве типа сообщения, идентификатором команды в качестве wParam и 1 в качестве lParam.

person Luaan    schedule 08.01.2014
comment
Спасибо за ваш ответ, это было очень полезно, знаете ли вы, как я могу получить значение из определенной ячейки в элементе управления сеткой данных? - person rcarubbi; 08.01.2014
comment
@rcarubbi Я боюсь, что сетка данных не является стандартным элементом управления Windows, поэтому вам, вероятно, придется глубже изучить фактическое приложение, которым вы пытаетесь управлять. Это в .NET WinForms, MFC, ...? - person Luaan; 09.01.2014
comment
Я понятия не имею, я думаю, что это было сделано с Delphi... это довольно старое приложение. - person rcarubbi; 10.01.2014
comment
@rcarubbi Delphi пыталась максимально придерживаться стандартного обмена сообщениями Windows, но если вы не можете использовать WM_GETTEXT или что-то подобное в самой ячейке сетки, вам, вероятно, не повезло. На самом деле, учитывая то, как сетки данных работают в Delphi, возможно, что значение ячеек на самом деле даже не загружено (например, при подключении к динамическому курсору базы данных он будет иметь значения только для видимых ячеек). Или, если это оболочка для представления списка окон, вы можете использовать эти сообщения окон (например, LVM_GETITEM). - person Luaan; 10.01.2014

Для этого вам нужно использовать вызовы Win32. GetWindow делает это

Справочная информация — http://msdn.microsoft.com/en-us/library/windows/desktop/ms633515%28v=vs.85%29.aspx

[DllImport("user32.dll")] public static extern int GetWindow(int hwnd,int wCmd); 
person realnero    schedule 08.01.2014
comment
Классы из пространства имен System.Windows.Automation делают это за кулисами. Первая строка из блока кода, который я разместил, выполняет точно такую ​​​​же работу. var mainWindow = AutomationElement.RootElement.FindChildByNamePart (управление бэк-офисом); К сожалению, проблема, с которой я столкнулся, глубже, чем просто получить окно. - person rcarubbi; 08.01.2014