以编程方式获取Windows应用程序的托盘菜单项

时间:2015-09-02 13:36:39

标签: winapi notification-area

我有一个带托盘菜单的应用程序,我正在尝试自动执行一些涉及托盘菜单的测试。基本上我需要获取托盘菜单的项目并用它们做些什么。 但是,我只能找到以编程方式获取应用程序内的菜单项的方法。但我的自动化测试将是一个外部应用程序,所以这对我没有帮助。

如何以编程方式获取外部应用程序的托盘菜单项?

3 个答案:

答案 0 :(得分:2)

有一些方法可以枚举/访问托盘图标本身(通常涉及挂钩到通知托盘本身,或使用UI自动化),但无法访问单击托盘图标时出现的弹出菜单。原因是因为图标的拥有应用程序在发生点击时会收到一条消息,然后相应地采取行动,这通常涉及显示自己的弹出菜单。没有与图标本身相关联的菜单。

对于您正在尝试的内容,您必须枚举图标并确定哪个图标属于您感兴趣的应用程序(这不是一项简单的任务),然后模拟图标上的单击以便应用程序显示它的弹出菜单。有关详细信息,请参阅以下问题:

Finding and simulating a click on a system tray icon?

一旦显示,与弹出菜单交互将更加困难。您将无法访问菜单本身。您可能不得不通过mouse_event()SendInput()发出鼠标事件来将鼠标光标移动到菜单上并单击其项目(假设它们出现在相对于图标的可预测位置)。

如果您可以获取图标的HWND + ID或GUID(通过挂钩通知托盘本身),您可以使用Shell_NotifyIconGetRect()来获取图标的坐标,至少。

答案 1 :(得分:1)

  

如何以编程方式获取外部应用程序的托盘菜单项?

你做不到。没有公共API可以访问通知图标。

答案 2 :(得分:0)

根据您认为可接受的假设类型,您可以在任务栏按钮的菜单可见后以编程方式与其进行交互。下图显示了OneNote剪切工具按钮菜单上的Inspect SDK工具报告属性。 (并且菜单项表示它们支持UIA Invoke Patten,因此它们应该通过UIA客户端代码以编程方式调用。)

如果要调用托盘按钮的菜单项,可以考虑使用UIA执行以下步骤。您可能会觉得我在这里做出的假设对您的情况是不可接受的。

  1. 找到具有类名" NotifyIconOverflowWindow"的元素,它是根菜单的直接子代。我假设按钮位于溢出区域。

  2. 枚举overflow元素的子元素,查找带有按钮名称的按钮。这假定UI语言已知且已计入。

  3. 获取按钮的边界矩形并模拟鼠标右键单击按钮。点击模拟是必要的,因为我打赌UI不支持IUIAutomationElement3 :: ShowContextMenu(),(但你总是可以尝试)。

  4. 上下文菜单启动后,找到一个带有ControlType元素的菜单,一个名称为&#34; Context&#34;,它是根元素的直接子元素。< / p>

  5. 获得菜单后,枚举菜单中的子元素以查找项目,并使用它们执行所需操作。例如,获取菜单项的Invoke模式并调用它。

  6. enter image description here