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

.net 避免在使用UI自动化时切换焦点,.net,wpf,focus,ui-automation,.net,Wpf,Focus,Ui Automation,出于好奇,我决定编写一个功能类似于的简单工具。基本上,它显示控件树并允许查看每个控件的属性。现在,我已经开始实现模式交互,并遇到了以下问题:只要用户在我的应用程序UI中单击例如“InvokePatter.Invoke”,自动化就会将焦点切换到我的目标应用程序。其他模式也是如此。它在原始UI Spy应用程序中的行为方式也相同 这种行为使得我的应用程序无法操作菜单,因为当我再次单击应用程序时,被测试的应用程序将失去焦点,菜单将被关闭。我想做的是使用UI自动化与应用程序交互,但保持我的(UI Spy)

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


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

如何使用每x(毫秒)秒运行一次的计时器,如果焦点丢失,该计时器将恢复焦点。

如何使用每x(毫秒)运行一次的计时器如果焦点丢失,秒将恢复焦点。

UIAutomation故意这样做:应用程序通常只希望在有焦点时接收输入。为了发送键盘输入,您必须首先对其进行聚焦。或者,如果您单击某个控件与之交互,它通常会在单击后获得焦点,然后执行操作。如果你不先发送焦点而发送输入,有些应用会变得非常混乱(有时甚至崩溃)

(例如,这些应用程序可能会初始化WM_SETFOCUS中的某些内部状态,并在接收到输入时依赖该状态。这不能真的被认为是一个bug,因为Windows实际上承诺在发送输入之前发送WM_SETFOCUS,所以它确实是发送“伪造”输入的工具,这违反了合同在这里。)

菜单是一个更棘手的例子:首先,在Windows中,菜单只出现在具有焦点的应用程序上。因此,要显示菜单,具有菜单的应用程序必须具有焦点,因此焦点必须从UISpy切换:没有办法。但菜单的真正问题不是UIAutomation将焦点切换到应用程序:而是单击工具(UISpy)这不是UIAutomation的问题,而是Win32如何处理菜单。所以这里真正的问题是:当单击该工具将关闭我正试图使用的菜单时,我如何使用工具来管理或操纵菜单

有几种方法可以解决这个问题,其中.Inspect.exe都是UISpy的旧MSAA前身,但是更新版本(作为SDK的一部分提供)现在支持MSAA和UIAutomation。以下技术仅在几个地方实现(例如SetFocus、导航命令,但不支持Invoke.Invoke()),但您可以根据需要在自己的工具中使用这些技术

它使用两种方法来解决这个问题:

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

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


或者,您也可以使用以下组合:使用热键触发鼠标指针所在工具中的命令-无论哪个对您有效。

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

(例如,这些应用程序可能会初始化WM_SETFOCUS中的某些内部状态,并在接收到输入时依赖该状态。这不能真的被认为是一个bug,因为Windows实际上承诺在发送输入之前发送WM_SETFOCUS,所以它确实是发送“伪造”输入的工具,这违反了合同在这里。)

菜单是一个更棘手的例子:首先,在Windows中,菜单只出现在具有焦点的应用程序上。因此,要显示菜单,具有菜单的应用程序必须具有焦点,因此焦点必须从UISpy切换:没有办法。但菜单的真正问题不是UIAutomation将焦点切换到应用程序:而是单击工具(UISpy)这不是UIAutomation的问题,而是Win32如何处理菜单。所以这里真正的问题是:当单击该工具将关闭我正试图使用的菜单时,我如何使用工具来管理或操纵菜单

有几种方法可以解决这个问题,其中.Inspect.exe都是UISpy的旧MSAA前身,但是更新版本(作为SDK的一部分提供)现在支持MSAA和UIAutomation。以下技术仅在几个地方实现(例如SetFocus、导航命令,但不支持Invoke.Invoke()),但是你可以在你身上使用这些技术