【问题标题】:Programmatically obtaining a Windows application's tray menu items以编程方式获取 Windows 应用程序的托盘菜单项
【发布时间】:2015-09-02 13:36:38
【问题描述】:

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

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

【问题讨论】:

  • 你尝试过 UI 自动化吗?
  • 您需要找到由外部应用程序公开的 API 才能可靠地执行此操作。如果您愿意在每次更新目标程序或 Windows 时更新您的程序,那么您可以使用 UI 自动化。

标签: winapi notification-area


【解决方案1】:

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

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

Finding and simulating a click on a system tray icon?

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

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

【讨论】:

    【解决方案2】:

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

    你不能。没有提供对通知图标的访问的公共 API。

    【讨论】:

      【解决方案3】:

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

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

      1. 查找类名为“NotifyIconOverflowWindow”的元素,它是根菜单的直接子级。我假设按钮在溢出区域。

      2. 枚举溢出元素的子元素,寻找与您的按钮名称相同的按钮。这假设 UI 语言是已知的并被解释。

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

      4. 打开上下文菜单后,找到具有 ControlType a Menu、名称为“Context”的元素,它是根元素的直接子元素。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-15
        • 1970-01-01
        • 2012-04-23
        相关资源
        最近更新 更多