【问题标题】:Finding and simulating a click on a system tray icon?查找并模拟单击系统托盘图标?
【发布时间】:2013-01-10 03:24:53
【问题描述】:

我需要弄清楚如何以编程方式从单独的应用程序的系统托盘图标中查找和选择上下文菜单项。我能想到的唯一方法是使用 mouse_event() 和一些硬编码的 x/y 值,并将图标设置为始终显示。除了一般硬编码的骇人听闻的使用之外,这里的问题是假设图标将保留它的位置(这可能会在另一个应用程序加载/卸载时中断)。我想知道是否有人知道其他方法可以解决这个问题?

【问题讨论】:

  • 使用 UI 自动化。通知图标是通知区域的可访问子项。
  • 这是 .NET 框架的标准部分吗?我似乎在对象浏览器中找不到任何合适的命名空间,而且它似乎没有在线记录。
  • 使用 UIA 的问题是你必须非常了解实际的 UI 布局 - 例如,如果一个图标是隐藏的,你需要知道找到并单击“显示隐藏图标”链接首先访问它。此外,UI 的结构在 Windows 版本之间总是会发生变化,因此它可能很脆弱。但这可能是任何解决上述 qu 的问题。使用 UIA 仍然远没有硬编码位置那么脆弱!

标签: windows winapi click contextmenu system-tray


【解决方案1】:

根据应用程序的编写方式,从上下文菜单中选择项目将导致WM_COMMAND 消息发布到属于应用程序的窗口。您可以使用 Spy++ 之类的工具来检查这一点。如果是这种情况,那么您所要做的(理论上)就是模拟该消息。

如果应用程序不使用WM_COMMAND 来接收来自上下文菜单的选择,那么您的工作就会困难得多。没有发现系统托盘项目的位置和标识的记录方法,因此硬编码 x/y 值的方法可能是您拥有的最佳选择。

【讨论】:

  • 不,您根本不需要那么长!使用 Spy++ 计算出消息发送到的窗口的类和标题,然后您可以使用FindWindowEx 自己找到该窗口并将消息发布。希望托盘图标根本不需要进入它。
  • 这些按钮没有出现在 Spy++ 中......至少不是作为系统托盘窗口的子窗口,它是一个名为“用户提升通知区域”的 ToolbarWindow32,所以你需要 AFAIK使用该窗口获取有关其相关按钮的信息,使用 Mark Hall 链接中描述的方法(我仍在测试)。
  • 当您从上下文菜单中选择一个命令时,WM_COMMAND 消息将发布到拥有托盘图标的窗口。它实际上根本没有进入托盘窗口。您需要停止将其视为托盘菜单命令,而应开始将其视为属于恰好从托盘菜单触发的应用程序的菜单。
  • 为什么要在 Spy++ 上显示单个按钮?忘记 ToolbarWindow32 - 它与此无关。
  • 托盘图标不能在没有窗口的情况下存在,因为它在屏幕上不可见并不意味着它不存在。窗口类和窗口标题几乎可以肯定总是相同的。使用 Spy++ 找出它们是什么。将这些字符串硬编码到您的应用程序中,然后您的应用程序可以调用 FindWindowEx 来查找窗口并将消息发布给它。
【解决方案2】:

请参阅此MSDN Forum article,其中讨论了如何找到系统托盘的句柄。该文章随后引用了CodeProject Article,了解如何找到您正在搜索的应用程序的句柄。我没有尝试过,但它看起来可能是一个可行的起点。

【讨论】:

  • 太棒了,谢谢!我会很快测试一下,然后用我的结果更新你。
  • CodeProject 文章中的代码似乎没有在给定 TBBUTTON 的 dwData 参数中分配任何内容。读取进程内存后(在 Win7 上),此值为零。我可以确认它确实找到了正确的按钮句柄,甚至为每个按钮分配了正确的工具提示文本,但是如果没有按钮的实际窗口句柄,就无法以编程方式使用它们的上下文菜单。
猜你喜欢
  • 2014-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-11
  • 1970-01-01
  • 1970-01-01
  • 2016-08-22
相关资源
最近更新 更多