繁体   English   中英

避免在使用UI自动化时切换焦点

[英]Avoid switching focus while using UI Automation

出于好奇,我决定编写一个功能类似于UI Spy的简单工具。 基本上,它显示控件树,并允许查看每个控件的属性。 现在,我已经开始实现模式交互,并遇到了以下问题:用户在应用程序中单击例如“ InvokePatter.Invoke”后,UI自动化开关就会将焦点集中在我要定位的应用程序上。 其他模式也是如此。 而且它在原始UI Spy应用程序中的行为也相同。

此行为使无法使用我的应用程序来操作菜单,因为当我再次单击我的应用程序时,被测试的应用程序失去了焦点并且菜单被关闭。 我想做的是使用UI自动化与应用程序进行交互,但要使我的(UI Spy)应用程序保持专注。 有什么想法要实现吗? 或者至少如何实现所需的功能-允许用户与菜单进行交互?

UIAutomation故意这样做:应用程序通常只希望在获得焦点时接收输入。 为了发送键盘输入,您必须先将其聚焦。 或者,如果您单击控件以与其进行交互,则通常是通过单击来获得焦点,然后执行操作。 如果某些应用程序在没有先发送焦点的情况下向其发送输入,则它们会变得非常混乱(有时甚至崩溃)。

(例如,这些应用可能会在WM_SETFOCUS中初始化一些内部状态,并在接收到输入时依赖于该状态已经准备好。这实际上不能视为错误,因为Windows本质上承诺会在发送输入之前发送WM_SETFOCUS,所以它将确实是发送“伪造”输入的工具,从而破坏了合同。)

菜单比较棘手:首先,在Windows中,菜单仅出现在具有焦点的应用程序中。 因此,要显示菜单,带有菜单的应用程序必须具有焦点,因此焦点必须从UISpy切换到其他位置:没有办法解决。 但是菜单的真正问题不是UIAutomation将焦点切换到应用程序:而是单击工具(UISpy)将导致菜单被关闭。 这不是UIAutomation的问题-而是Win32处理菜单的方式。 因此,这里真正的问题是:如何使用工具浏览器或以其他方式操作菜单,单击该工具将关闭我尝试使用的菜单?

有两种解决方法-两种检查对象工具(inspect.exe)都使用 Inspect.exe是UISpy的MSAA的旧版本,但是更新版本(作为SDK的一部分提供)现在支持MSAA和UIAutomation。 以下技术仅在几个地方实现(例如,SetFocus,导航命令,而不是Invoke.Invoke()),但是您可以在自己的工具中适当使用这些技术。

使用两种方法可以解决此问题:

  • 热键-热键本身不会更改焦点或关闭菜单-因此,请使用RegisterHotKey()为可能要在当前对象上执行的每个操作分配一个热键(例如Ctrl-Shift-X)。 现在,当目标应用程序聚焦并且菜单出现时,您可以使用热键组合向该工具发出信号以执行适当的操作。

  • 创造性地使用鼠标:您不能使用鼠标来单击UI,但是仍然可以利用鼠标的位置。 Inspect具有“活动悬停工具栏”选项(在“选项”菜单下):选中后,如果将鼠标悬停在工具栏项上几秒钟,它将被视为单击。 例如,这使您可以浏览菜单项,而无需实际单击任何Inspect UI。 在内部,它可能使用轮询和TB_HITTEST的某种组合来确定指针位于哪个按钮上。

或者,您也可以组合使用以下两种方法:使用热键触发鼠标指针悬停在工具中的命令-任您选择。

每隔x(毫秒)运行一次的计时器如何处理,如果焦点丢失,该计时器将使焦点重新返回。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM