我想获取win32旧版控件的工具提示文本(不是本身支持UI Automation的WPF控件)。
我做了什么:
AutomationElement
及其边界矩形Thread.Sleep(1500)
等待工具提示控件弹出; tooltipAutomationElement
的子窗口"Tooltip"
; tooltipAutomationElement
获取此工具提示的名称属性,该属性对应于工具提示字符串。这实际上有效,但惩罚是:我必须sleep(1500)
并手动等待工具提示出现(5-20个按钮将被扫描工具提示字符串),这与性能要求不符。
预期结果(不确定是否可行)
更新1 :对于TTN_NEEDTEXT
,MSDN doc似乎不太清楚,我也不知道如何使用C#对其进行编程。可以找到与工具提示控制相关的低级结构/消息的相关链接之一here。
更新2 :那些相信这可以通过...完成的人,我会说,说起来容易做起来难。我欢迎那些尝试过对此发表评论的人,如果你能提供一些证据来展示其适用性和功效,那么欢迎一些表面上可行的解决方案。
更新3 :如果我们尝试最小化TTM_SETDELAYTIME
,以便N
中的sleep(N)
可以最小化,那么在经过一些实验后这不起作用。我们只能在工具提示窗口句柄存在后进行调整。 e.g。
SendMessage(_tooltipCtrl.Handle, TTM_SETDELAYTIME, _TTDT_INITIAL, 10); //10 ms
更新4 :使用TTM_GETTEXTA
消息似乎是一个解决方案,但是,它类似于Update 3,我们需要tooltipCtrl
的句柄,这是仅在创建工具提示后才可用,因为要创建此工具提示,我们别无选择,只能将鼠标光标悬停在工具上方,这似乎存在性能问题(Thread.Sleep
),如上所述。
SendMessage(_tooltipCtrl.Handle, TTM_GETTEXTA, 0, ti);
更新5 :“如何获取工具提示文本”使用传统方法使用InterOp(PInvoke)或Automation UI(鼠标悬停在工具窗口上,找到Hwnd句柄,然后获取其文本。 ..)不是这篇文章的关注点。预期结果:我们是否可以提取控件的工具提示字符串(例如按钮)而无需悬停在控件上?如果有,怎么样?
更新6 :使用WM_MOUSEHOVER激活工具提示窗口似乎不起作用,我已经使用SendMessage(...)测试了正确的wparam和lparam填充,但是静脉。
答案 0 :(得分:3)
只是一个想法,但尝试使用消息而不是利用实际的鼠标。
玩WM_HOVER,WM_MOUSEHOVER,WM_MOUSEENTER
SendMessage(_buttonCtrl.Handle, WM_MOUSEHOVER, ..., ...)
等
您的屏幕截图看起来像一个自定义控件,所以这将是一个黑客问题,找出触发工具提示的内容。
您可以同时发送几个WM_MOUSEENTER或WM_MOUSEHOVER。这实际上取决于底层代码。
如果这导致了太长的延迟,(并且没有建议的解决方案有效),请考虑将工具提示测试拉入次要测试池,该测试池执行频率较低或仅在特定请求时执行。
另外......我确定你已经尝试过了......但如果没有,请查看UI Spy并查看它是否在实际生成之前报告有关工具提示的任何信息。
答案 1 :(得分:1)
从UI Automation的角度来看,我们可以做的最好的事情就是订阅ToolTip Opened Event并在事件处理程序中处理相同的事情。此链接包含示例http://msdn.microsoft.com/en-us/library/ms752286.aspx。可以在http://msdn.microsoft.com/en-us/library/ms748252.aspx找到UI自动化事件列表。有关AutomationElement.ToolTipOpenedEvent的详细信息,请访问http://msdn.microsoft.com/en-us/library/system.windows.automation.automationelement.tooltipopenedevent.aspx。
至少使用UI自动化,我们应该让事情发生,无论是点击按钮还是打开窗口或显示工具提示。因此,订阅ToolTip事件将在这里完成工作,其性能优于硬Sleep()延迟。否则,少数人提到的hacky方式(虽然不是端到端)是预先获取工具提示字符串的资源字符串ID,并在执行自动化测试期间验证资源字符串。
答案 2 :(得分:0)
将工具提示的父类子类化,即将按钮的windproc 替换为您的并过滤WM_NOTIFY
的TTN_GETDISPINFO
情况,可能像这样..
case TTN_GETDISPINFO:
{
// do this first
NMTTDISPINFO pttdi = (LPNMTTDISPINFO)lparam;
// next let the system do the default, ie fill the
// relevant structures with the
// text that will appear on the tooltip.
// so
CallWindowProc(OldListViewProc, hwnd, message, wparam, lparam);
// then the text you seek will be in the
// NMTTDISPINFO pttdi structure. You can even alter
// the text to suit your needs if you want.
}
显然,Visual Studio 2008 的 MSDN 库显示,对于 _WIN32_WINNT >= 0x0600,即在Vista之后,这个结构HBITMAP hbmp有一个额外的成员,它有点隐藏,但代表“要在工具提示中显示的大预览位图的句柄”。