首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >UI自动化- #32770 (对话框)显示在Insepct.exe中,而不是在VisualUIAVerifyNative.exe中

UI自动化- #32770 (对话框)显示在Insepct.exe中,而不是在VisualUIAVerifyNative.exe中
EN

Stack Overflow用户
提问于 2016-06-19 07:00:22
回答 3查看 1.7K关注 0票数 1

我正在尝试通过使用UI自动化ClassName API来自动化一个子窗口(带有C# #32770的对话框)。

目标子窗口显示在Spy++Inspect.exe中,但在中没有显示AutomationElement.FindFirst或TreeWalker导航也无法访问它。

我在VisualUIAVerifyNative中查看了这棵树,发现它与Spy++和Inspect.exe中的树非常不同。

有趣的事情:

  1. 我的C#代码的行为似乎与VisualUIAVerifyNative完全一样。
  2. 我可以使用AutomationElement.FromHandle绑定对话框的HWND

你知道为什么会这样吗?

下面是Insepct.exe对话框的详细内容

代码语言:javascript
运行
复制
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没有。

EN

回答 3

Stack Overflow用户

发布于 2016-06-20 13:19:08

这是本机COM和托管API之间的一个已知差异(.NET特有的bug)。以下是大多数流行语言的如何通过COM对象使用UIA示例,包括C#。

票数 2
EN

Stack Overflow用户

发布于 2017-09-11 06:24:55

今天,我解决了去年的一个类似的问题,直到现在我才有时间再讨论这个问题。

我的问题是,应用程序的模态对话框无法用UIAutomation接口找到(我尝试了C中的原生COM调用,以及使用所有可能的UIA方法使用C#的其他方法,但都没有成功),inspect.exe展示了它非常容易,非常类似于您的,可能相同。

所以,当我尝试用FindWindowEx方法找到相同的对话框时,效果很好。一个令我惊讶的问题是,该对话框显示在它的应用程序的主窗口下,在检查的树层次结构中,但是只有当我以桌面子程序的身份搜索对话框时,FindWindowEx才会成功--我认为在某些情况下会出现这种情况,例如,如果您没有正确设置ShowDialog()接收器的父程序,它会附加到桌面上。

这可能会回答一些其他问题,我有关于检查的行为。推测一下,我认为这可能是使用winapi调用来查找窗口,并生成一个与实际情况略有不同的树层次结构,从而导致我们这些贫穷用户长期困惑。糟糕的设计。

这是一些代码,如果你还想在一年后尝试,或者帮助其他人。若要在桌面下查找窗口:

首先定义如下:

代码语言:javascript
运行
复制
 [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);

然后打电话:

代码语言:javascript
运行
复制
IntPtr w = FindWindowEx(IntPtr.Zero, IntPtr.Zero, (string)null, "V6 - or your dialog's name");

或者将其作为顶层窗口的子窗口(从IUIAutomation.CurrentNativeWindowHandle查找它的句柄,比如将其设置为var句柄):

代码语言:javascript
运行
复制
IntPtr w = FindWindowEx(handle, IntPtr.Zero, (string)null, "V6 - or your dialog's name");

然后可以使用IUIAutomation.ElementFromHandle()尝试w。

票数 2
EN

Stack Overflow用户

发布于 2021-09-16 04:00:00

虽然问的问题比较老,但我有类似的问题,并解决了如下。由于对话框的IsControlElement属性为false,所以您可以使用RawViewWalker访问该对话框。这是样品。

代码语言:javascript
运行
复制
            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扩展方法放在静态类中,否则会显示错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37904741

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档