Beim Aufrufen eines Untermenüelements mit UIAutomationClient können Untermenüelemente nicht gefunden werdenC#

Ein Treffpunkt für C#-Programmierer
Guest
 Beim Aufrufen eines Untermenüelements mit UIAutomationClient können Untermenüelemente nicht gefunden werden

Post by Guest »

Ich habe gesehen, wie diese Frage mit verschiedenen Frameworks gestellt und beantwortet wurde, jedoch nicht mit C# und Interop.UIAutomationClient und .NET 8.0. Die Antwort ist immer dieselbe. Stellen Sie sicher, dass Sie den Menüpunkt erweitern, bevor Sie Untermenüpunkte finden. Ich mache das, da es sich um Code handelt, der von einer .NET-Windows-Anwendung mithilfe von AutomationElement in eine Konsolen-App verschoben wird, in der meine Optionen anscheinend COM-Objekte für die Automatisierung verwenden. Ich habe ein paar Klassen geschrieben, um die Arbeit zu erledigen.
Eine Element-Wrapper-Klasse für die Fensterautomatisierung, die einige Muster für ein Element unterstützt.

Code: Select all

    public class WindowElement
{
private IUIAutomationElement? element;

public WindowElement(IUIAutomationElement element)
{
this.element = element;
}

public WindowElement()
{
}

public bool IsValid()
{
return element != null;
}

public IUIAutomationElement GetElement()
{
return element;
}

public bool Expand()
{
if (element != null)
{
IUIAutomationExpandCollapsePattern pattern = element.GetCurrentPattern(WindowAutomation.UIA_ExpandCollapsePatternId);
pattern.Expand();
return pattern.CurrentExpandCollapseState == ExpandCollapseState.ExpandCollapseState_Expanded;
}
return false;
}

public bool Invoke()
{
if (element != null)
{
IUIAutomationInvokePattern pattern = element.GetCurrentPattern(WindowAutomation.UIA_InvokePatternId);
pattern.Invoke();
return true;
}
return false;
}

public bool Select()
{
if (element != null)
{
IUIAutomationSelectionItemPattern pattern = element.GetCurrentPattern(WindowAutomation.UIA_SelectionItemPatternId);
pattern.Select();
return true;
}
return false;
}
}
Eine Klasse, die dazu dient, Elemente zu finden, indem eine bekannte Anwendung anhand der Prozess-ID (für den Start eines Unterprozesses) oder anhand eines bekannten Programmnamens gefunden wird.

Code: Select all

public class WindowAutomation
{
private CUIAutomation8 uia = new CUIAutomation8();

public WindowElement FindProcessNameElement(string processName)
{
IUIAutomationElement root = uia.GetRootElement();
IUIAutomationElementArray children = root.FindAll(TreeScope.TreeScope_Children, uia.CreateTrueCondition());
for (int i = 0; i < children.Length; i++)
{
IUIAutomationElement child = children.GetElement(i);
string childName = child.CurrentName;
if (childName.StartsWith(processName))
{
return new WindowElement(child);
}
}
return new WindowElement();
}

public WindowElement FindMenuBarItem(WindowElement appElement, string itemName)
{
if (appElement.IsValid())
{
IUIAutomationElementArray items = appElement.GetElement().FindAll(TreeScope.TreeScope_Children, uia.CreatePropertyCondition(UIA_ControlTypePropertyId, UIA_MenuBarControlTypeId));
if (items.Length > 0)
{
items = items.GetElement(0).FindAll(TreeScope.TreeScope_Children, uia.CreatePropertyCondition(UIA_ControlTypePropertyId, UIA_MenuItemControlTypeId));
for (int i = 0; i < items.Length; i++)
{
IUIAutomationElement item = items.GetElement(i);
if (item.CurrentName == itemName)
{
return new WindowElement(item);
}
}
}
}
return new WindowElement();
}

public WindowElement FindSubmenuItem(WindowElement menuItem, string subitemName)
{
if (menuItem.IsValid())
{
menuItem.Expand();
IUIAutomationElementArray items = menuItem.GetElement().FindAll(TreeScope.TreeScope_Descendants, uia.CreatePropertyCondition(UIA_ControlTypePropertyId, UIA_MenuItemControlTypeId));
if (items.Length > 0)
{
for (int i = 0; i < items.Length;  i++)
{
IUIAutomationElement item = items.GetElement(i);
string name = item.CurrentName;
if (item.CurrentName == subitemName)
{
return new WindowElement(item);
}
}
}
}
return new WindowElement();
}`
Wenn ich die Untermenüpunkte finde, erhalte ich nie Ergebnisse. Ich habe andere Antworten gelesen, die besagen, dass unbedingt TreeScope_Descendants verwendet werden muss, was ich auch getan habe. Und dann natürlich Antworten, die besagen, dass Sie das Menü erweitern müssen, was ich getan habe und deutlich sehen kann, dass es funktioniert.

Code: Select all

WindowElement app = ui.FindProcessNameElement("gMotor2 MAS");
WindowElement fileMenu = ui.FindMenuBarItem(app, "File");
if (fileMenu.Expand())
{
Console.WriteLine("Expanded file menu");
}
WindowElement exitItem = ui.FindSubmenuItem(fileMenu, "Exit");
exitItem.Invoke();
Ich habe erwartet, dass Invoke() die Anwendung beendet. Ich sehe, wie sich das Menü erweitert, aber da ich die Untermenüelemente nie zurückbekomme, führt der Aufruf von für „exitItem“ zu nichts.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post