我正在尝试通过使用UI自动化ClassName API来自动化一个子窗口(带有C# #32770的对话框)。
目标子窗口显示在Spy++和Inspect.exe中,但在中没有显示AutomationElement.FindFirst或TreeWalker导航也无法访问它。
我在VisualUIAVerifyNative中查看了这棵树,发现它与Spy++和Inspect.exe中的树非常不同。
有趣的事情:
你知道为什么会这样吗?
下面是Insepct.exe对话框的详细内容
How found: Selected from tree...
Name: "V6"
ControlType: UIA_PaneControlTypeId (0xC371)
LocalizedControlType: "Dialog"
BoundingRectangle: {l:-47997 t:-47997 r:-46107 b:-47553}
IsEnabled: true
HasKeyboardFocus: false
ProcessId: 15496
RuntimeId: [2A.140BD8]
FrameworkId: "Win32"
ClassName: "#32770"
NativeWindowHandle: 0x140BD8
IsControlElement: false
IsContentElement: false
ProviderDescription: "[pid:10556,hwnd:0x140BD8 Main:Microsoft: Container Proxy (unmanaged:uiautomationcore.dll); Hwnd(parent link):Microsoft: HWND Proxy (unmanaged:uiautomationcore.dll)]"
LegacyIAccessible.ChildId: 0
LegacyIAccessible.Name: "V6"
LegacyIAccessible.Role: Dialog (0x12)
LegacyIAccessible.State: (0x100000)
IsAnnotationPatternAvailable: false
IsDragPatternAvailable: false
IsDockPatternAvailable: false
IsDropTargetPatternAvailable: false
IsExpandCollapsePatternAvailable: false
IsGridItemPatternAvailable: false
IsGridPatternAvailable: false
IsInvokePatternAvailable: false
IsItemContainerPatternAvailable: false
IsLegacyIAccessiblePatternAvailable: true
IsMultipleViewPatternAvailable: false
IsObjectModelPatternAvailable: false
IsRangeValuePatternAvailable: false
IsScrollItemPatternAvailable: false
IsScrollPatternAvailable: false
IsSelectionItemPatternAvailable: false
IsSelectionPatternAvailable: false
IsSpreadsheetItemPatternAvailable: false
IsSpreadsheetPatternAvailable: false
IsStylesPatternAvailable: false
IsSynchronizedInputPatternAvailable: false
IsTableItemPatternAvailable: false
IsTablePatternAvailable: false
IsTextChildPatternAvailable: false
IsTextEditPatternAvailable: false
IsTextPatternAvailable: false
IsTextPattern2Available: false
IsTogglePatternAvailable: false
IsTransformPatternAvailable: false
IsTransform2PatternAvailable: false
IsValuePatternAvailable: false
IsVirtualizedItemPatternAvailable: false
IsWindowPatternAvailable: false
...
刚找到这个https://stackoverflow.com/a/14187618/1633272。
我试过TreeWalker.RawViewWalker,它成功了。然而,TreeWalker.ControlViewWalker没有。
发布于 2016-06-20 13:19:08
这是本机COM和托管API之间的一个已知差异(.NET特有的bug)。以下是大多数流行语言的如何通过COM对象使用UIA示例,包括C#。
发布于 2017-09-11 06:24:55
今天,我解决了去年的一个类似的问题,直到现在我才有时间再讨论这个问题。
我的问题是,应用程序的模态对话框无法用UIAutomation接口找到(我尝试了C中的原生COM调用,以及使用所有可能的UIA方法使用C#的其他方法,但都没有成功),inspect.exe展示了它非常容易,非常类似于您的,可能相同。
所以,当我尝试用FindWindowEx方法找到相同的对话框时,效果很好。一个令我惊讶的问题是,该对话框显示在它的应用程序的主窗口下,在检查的树层次结构中,但是只有当我以桌面子程序的身份搜索对话框时,FindWindowEx才会成功--我认为在某些情况下会出现这种情况,例如,如果您没有正确设置ShowDialog()接收器的父程序,它会附加到桌面上。
这可能会回答一些其他问题,我有关于检查的行为。推测一下,我认为这可能是使用winapi调用来查找窗口,并生成一个与实际情况略有不同的树层次结构,从而导致我们这些贫穷用户长期困惑。糟糕的设计。
这是一些代码,如果你还想在一年后尝试,或者帮助其他人。若要在桌面下查找窗口:
首先定义如下:
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
然后打电话:
IntPtr w = FindWindowEx(IntPtr.Zero, IntPtr.Zero, (string)null, "V6 - or your dialog's name");
或者将其作为顶层窗口的子窗口(从IUIAutomation.CurrentNativeWindowHandle查找它的句柄,比如将其设置为var句柄):
IntPtr w = FindWindowEx(handle, IntPtr.Zero, (string)null, "V6 - or your dialog's name");
然后可以使用IUIAutomation.ElementFromHandle()尝试w。
发布于 2021-09-16 04:00:00
虽然问的问题比较老,但我有类似的问题,并解决了如下。由于对话框的IsControlElement属性为false,所以您可以使用RawViewWalker访问该对话框。这是样品。
IEnumerable<AutomationElement> controlElements = GetChildren(parentAutomationElement);
AutomationElement automationElement = null;
foreach (var element in controlElements)
{
if (element.Current.ClassName == "#32770")
{
automationElement = element;
break;
}
}`
private List<AutomationElement> GetChildren(AutomationElement parent)
{
if (parent == null)
{
// null parameter
throw new ArgumentException();
}
IEnumerable<AutomationElement> collection = parent.FindInRawView();
if (collection != null)
{
List<AutomationElement> result = new List<AutomationElement>(collection.Cast<AutomationElement>());
return result;
}
else
{
// some error occured
return null;
}
}
public static IEnumerable<AutomationElement> FindInRawView(this AutomationElement root)
{
TreeWalker rawViewWalker = TreeWalker.RawViewWalker;
Queue<AutomationElement> queue = new Queue<AutomationElement>();
queue.Enqueue(root);
while (queue.Count > 0)
{
var element = queue.Dequeue();
yield return element;
var sibling = rawViewWalker.GetNextSibling(element);
if (sibling != null)
{
queue.Enqueue(sibling);
}
var child = rawViewWalker.GetFirstChild(element);
if (child != null)
{
queue.Enqueue(child);
}
}
}
确保将FindInRawView扩展方法放在静态类中,否则会显示错误。
https://stackoverflow.com/questions/37904741
复制相似问题