[英]Align Menu Strip in Center of a parent container control of Winform Application
[英]UI Automation Control Desktop Application and Click on Menu Strip
我正在使用 UI 自動化單擊菜單條控件。
我已經預先填充了文本框,現在也可以調用按鈕了。
但是我想遍歷到菜單欄選擇一個選項讓我們說應該打開它的子菜單項的文件,然后單擊子菜單按鈕,比如說退出。
我怎樣才能實現它,下面是我的代碼,直到現在,
AutomationElement rootElement = AutomationElement.RootElement;
if (rootElement != null)
{
System.Windows.Automation.Condition condition = new PropertyCondition
(AutomationElement.NameProperty, "This Is My Title");
rootElement.FindAll(TreeScope.Children, condition1);
AutomationElement appElement = rootElement.FindFirst(TreeScope.Children, condition);
if (appElement != null)
{
foreach (var el in eles)
{
AutomationElement txtElementA = GetTextElement(appElement, el.textboxid);
if (txtElementA != null)
{
ValuePattern valuePatternA =
txtElementA.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
valuePatternA.SetValue(el.value);
el.found = true;
}
}
System.Threading.Thread.Sleep(5000);
System.Windows.Automation.Condition condition1 = new PropertyCondition
(AutomationElement.AutomationIdProperty, "button1");
AutomationElement btnElement = appElement.FindFirst
(TreeScope.Descendants, condition1);
InvokePattern btnPattern =
btnElement.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
btnPattern.Invoke();
菜單項支持ExpandCollapsePattern 。 您可以在展開子MenuItem
后調用它。 這將創建MenuItem
后代對象。 如果您不展開 Menu,則它沒有后代,因此沒有任何可調用的內容。
使用InvokePattern執行調用
要獲取ExpandCollapsePattern
和InvokePattern
,請使用TryGetCurrentPattern方法:
[MenuItem].TryGetCurrentPattern(ExpandCollapsePattern.Pattern, out object pattern)
[MenuItem].TryGetCurrentPattern(InvokePattern.Pattern, out object pattern)
如果該方法返回成功的結果,則可以調用Expand()和Invoke()方法。
要注意MenuBar元素有Children
,而MenuItem有Descendants
。 如果您使用FindAll()方法搜索子項,您將找不到任何子項。
Inspect 實用程序在編寫 UI 自動化過程時非常有用。 它通常位於:
C:\\Program Files (x86)\\Windows Kits\\10\\bin\\x64\\inspect.exe
32 位版本可用(
\\bin\\x86\\
文件夾)。
如何進行:
MenuBar
自動化MenuBar
。
SystemMenu
也包含在MenuBar
,可以使用元素名稱確定它,它包含: "System"
而不是"Application"
。MenuBar
或FindFirst()的子元素。
ExpandCollapsePattern.Expand()
方法展開 Menu,以創建其 Descendants 元素。Name
或AutomationId
或AccessKey
查找子菜單元素AccessKey
。InvokePattern.Invoke()
方法調用子菜單操作。當然,可以重復相同的操作來擴展和調用嵌套子菜單的 MenuItem。
用於查找和展開Notepad.exe
的文件菜單並調用Exit
MenuItem 操作的示例代碼和幫助程序方法:
public void CloseNotepad()
{
IntPtr hWnd = IntPtr.Zero;
using (Process p = Process.GetProcessesByName("notepad").FirstOrDefault()) {
hWnd = p.MainWindowHandle;
}
if (hWnd == IntPtr.Zero) return;
var window = GetMainWindowElement(hWnd);
var menuBar = GetWindowMenuBarElement(window);
var fileMenu = GetMenuBarMenuByName(menuBar, "File");
if (fileMenu is null) return;
// var fileSubMenus = GetMenuSubMenuList(fileMenu);
bool result = InvokeSubMenuItemByName(fileMenu, "Exit", true);
}
private AutomationElement GetMainWindowElement(IntPtr hWnd)
=> AutomationElement.FromHandle(hWnd) as AutomationElement;
private AutomationElement GetWindowMenuBarElement(AutomationElement window)
{
var condMenuBar = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.MenuBar);
var menuBar = window.FindAll(TreeScope.Descendants, condMenuBar)
.OfType<AutomationElement>().FirstOrDefault(ui => !ui.Current.Name.Contains("System"));
return menuBar;
}
private AutomationElement GetMenuBarMenuByName(AutomationElement menuBar, string menuName)
{
var condition = new AndCondition(
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.MenuItem),
new PropertyCondition(AutomationElement.NameProperty, menuName)
);
if (menuBar.Current.ControlType != ControlType.MenuBar) return null;
var menuItem = menuBar.FindFirst(TreeScope.Children, condition);
return menuItem;
}
private List<AutomationElement> GetMenuSubMenuList(AutomationElement menu)
{
if (menu.Current.ControlType != ControlType.MenuItem) return null;
ExpandMenu(menu);
var submenus = new List<AutomationElement>();
submenus.AddRange(menu.FindAll(TreeScope.Descendants,
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.MenuItem))
.OfType<AutomationElement>().ToArray());
return submenus;
}
private bool InvokeSubMenuItemByName(AutomationElement menuItem, string menuName, bool exactMatch)
{
var subMenus = GetMenuSubMenuList(menuItem);
AutomationElement namedMenu = null;
if (exactMatch) {
namedMenu = subMenus.FirstOrDefault(elm => elm.Current.Name.Equals(menuName));
}
else {
namedMenu = subMenus.FirstOrDefault(elm => elm.Current.Name.Contains(menuName));
}
if (namedMenu is null) return false;
InvokeMenu(namedMenu);
return true;
}
private void ExpandMenu(AutomationElement menu)
{
if (menu.TryGetCurrentPattern(ExpandCollapsePattern.Pattern, out object pattern))
{
(pattern as ExpandCollapsePattern).Expand();
}
}
private void InvokeMenu(AutomationElement menu)
{
if (menu.TryGetCurrentPattern(InvokePattern.Pattern, out object pattern))
{
(pattern as InvokePattern).Invoke();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.