以编程方式获取Win32传统控件的工具提示文本

我想获得win32遗留控件的工具提示文本(不是WPF控件本身支持UI自动化 )。

按钮的屏幕截图

我做了什么:

  • 给定一个感兴趣的按钮,我有它的AutomationElement ,以及它的边界矩形
  • 我将鼠标移到了这个按钮上(代码中);
  • Thread.Sleep(1500)等待弹出工具提示控件;
  • 枚举Desktop的所有子窗口,并获取子窗口tooltipAutomationElement ,其类型为"Tooltip" ;
  • tooltipAutomationElement获取此工具提示的name属性,该属性对应于工具提示字符串。

这实际上是有效的,但惩罚是:我必须sleep(1500)并手动等待工具提示出现(5-20​​个按钮将被扫描工具提示字符串),这与性能要求不符。

预期结果(不确定是否可行)

  • 以编程方式获取按钮的工具提示字符串,而不需要显示工具提示
  • 无需逐个鼠标放在每个按钮上。

更新1 :对于TTN_NEEDTEXT ,MSDN doc似乎不是很清楚,我不知道如何使用C#编程。 可以在此处找到与工具提示控制相关的低级结构/消息的相关链接之一。

更新2 :那些相信这可以通过……完成的人,我会说,说起来容易做起来难。 我欢迎那些尝试过的人,对此发表评论,如果你能提供一些证据来certificate其适用性和功效,我欢迎一些表面上可行的解决方案。

更新3 :如果我们尝试最小化TTM_SETDELAYTIME以使sleep(N)最小化,则在一些实验之后这不起作用。 我们只能在工具提示窗口句柄存在后进行调整。 例如

 SendMessage(_tooltipCtrl.Handle, TTM_SETDELAYTIME, _TTDT_INITIAL, 10); //10 ms 

更新4 :使用TTM_GETTEXTA消息似乎是一个解决方案,但是,它类似于Update 3,我们需要tooltipCtrl的句柄,只有在创建工具提示后才可用,因为要创建此工具提示,我们没有选择,但将鼠标光标hover在工具上方,这似乎有如上所述的性能问题( Thread.Sleep )。

 SendMessage(_tooltipCtrl.Handle, TTM_GETTEXTA, 0, ti); 

更新5 :“如何获取工具提示文本”使用InterOp(PInvoke)或Automation UI使用传统方法(鼠标hover在工具窗口上,找到Hwnd句柄,然后获取其文本…)不是这篇文章的关注点。 预期结果: 我们可以提取控件的工具提示字符串(比如一个按钮)而不需要hover在控件上吗? 如果有,怎么样?

更新6 :使用WM_MOUSEHOVER激活工具提示窗口似乎不起作用,我已经使用SendMessage(…)测试了正确的wparam和lparam填充,但静脉。

只是一个想法,但尝试使用消息而不是利用实际的鼠标。

玩WM_HOVER,WM_MOUSEHOVER,WM_MOUSEENTER

  SendMessage(_buttonCtrl.Handle, WM_MOUSEHOVER, ..., ...) 

等等

您的屏幕截图看起来像一个自定义控件,所以这将是一个黑客的问题,以找出触发工具提示的内容。

可能您可以同时发送几个WM_MOUSEENTER或WM_MOUSEHOVER。 这实际上取决于底层代码。

如果这导致了太长的延迟,(并且没有建议的解决方案有效)考虑将工具提示测试拉入次要测试池,该测试池执行频率较低或仅在特定请求时执行。

另外……我确定你已经尝试过了……但如果没有,请查看UI间谍 ,看看它是否在实际生成之前报告了有关工具提示的任何信息。

从UI Automation的角度来看,我们可以做的最好的事情就是订阅ToolTip Opened Event并在事件处理程序中处理相同的事情。 此链接有一个示例http://msdn.microsoft.com/en-us/library/ms752286.aspx 。 UI自动化事件列表可以在http://msdn.microsoft.com/en-us/library/ms748252.aspx找到。 有关AutomationElement.ToolTipOpenedEvent的详细信息,请访问http://msdn.microsoft.com/en-us/library/system.windows.automation.automationelement.tooltipopenedevent.aspx 。

至少使用UI自动化,我们应该让事情发生,无论是点击按钮还是打开窗口或显示工具提示。 因此,订阅ToolTip事件将在这里完成工作,其性能优于硬Sleep()延迟。 否则,少数人提到的hacky方式(虽然不是端到端)是提前获取工具提示字符串的资源字符串ID,并在执行自动化测试期间validation资源字符串。