如何隐藏其他应用程序/进程的系统托盘图标(从我的应用程序中)?

3

有人能向我展示如何使用我的应用程序隐藏/显示其他应用程序/进程的托盘图标吗? 我想从我的应用程序中隐藏“连接到互联网”图标(当数据发送/接收/两者都是时,那两个变蓝的计算机)
编辑:我可以使用从http://scalabium.com/faq/dct0147.htm获取的此代码片段隐藏系统时钟。

ShowWindow(FindWindowEx(FindWindowEx(FindWindow('Shell_TrayWnd', nil), 0, 'TrayNotifyWnd', nil), 0, 'TrayClockWClass', nil), SW_HIDE);

我想我可以使用这段代码来隐藏“网络连接图标”(顺便问一下,那个图标叫什么?),只需将TrayClockWClass替换为其他类即可。我尝试使用名为windowse的工具查找类名,但没有成功。
编辑2:我可以通过左键单击“托盘窗口”,然后选择属性,在属性窗口上单击“自定义”按钮,然后将图标属性从“不活动时隐藏”更改为“始终隐藏”来隐藏Windows中的这些图标。我能否在Delphi中实现此功能,甚至更好的是,是否可以随时使用Delphi隐藏/显示(完全)该图标。

7
为什么你要这样做?为什么不找出控制系统来隐藏/显示托盘所使用的内容(可能在注册表中),而不是干扰别人的电脑。干预这些东西会给人们带来麻烦。网络图标由控制面板控制,所以找到关闭它们的注册表选项即可完成任务。 - mj2008
我不会去干扰别人的电脑,我正在编写一个个人程序,参见编辑2。如果我通过注册表来实现它,那么每次都需要重新启动我的电脑吗?我想要通过按钮点击在我的程序中快速地隐藏/显示。 - Omair Iqbal
可以通过双击托盘图标,选择属性,然后取消选中“连接时在通知区域显示图标”框来隐藏Internet连接图标。 - Gerry Coll
@gerry:是的,但现在我该如何将它带回来?并且是否可以使用任何编程语言、设置、批处理程序脚本自动化?基本上我想要编写的程序是能够节省任务栏空间的东西。更多的任务栏托盘图标会使我的任务栏空间变得拥挤,我打开了很多占据任务栏空间的IE窗口,当我需要时,我需要隐藏和恢复托盘图标,这就是为什么我问的原因。 - Omair Iqbal
@gerry:自动化并不重要,但如果您能告诉我如何将其恢复并且有类似热键之类的东西将其带回来,那将是很好的。 - Omair Iqbal
3个回答

4
API不提供访问其他应用程序图标的接口。唯一的选择是子类化系统托盘本身,以拦截Shell_NotifyIcon()发送给它的窗口消息,这样您就可以跟踪哪个HWND注册了哪个图标ID。

没有编程方式可以访问操作系统内置的“非活动时隐藏”和“始终隐藏”功能。再次强调,唯一访问和操作他人图标的方法是直接钩取系统托盘窗口并拦截Shell_NotifyIcon()的WM_COPYDATA消息(请参阅http://www.codeproject.com/KB/applications/ShellTrayInfo.aspx了解消息内容),以便您可以访问每个图标的HWND和ID,从而可以对Shell_NotifyIcon()进行自己的调用,或者仅仅阻止消息,使图标根本不会到达系统托盘。 - Remy Lebeau
谢谢,这正是我在寻找的答案。像 WM_COPYDATA 这样的消息不是 Windows API 的一部分吗?此外,示例是用 C++ 编写的(我不会:-(),你有 Delphi 示例的链接吗? - Omair Iqbal
WM_COPYDATA是一种通用消息,用于在窗口之间传递任意数据块。Shell_NotifyIcon()内部使用它的事实是Microsoft的私有实现细节,未来可以自由更改而不影响使用Shell_NotifyIcon()的代码。但目前它使用WM_COPYDATA已经很长时间了。不过,我没有提到早期文章的Delphi示例。 - Remy Lebeau

3
你提到的时钟示例是有效的,因为尽管时钟图标位于通知栏相同的区域,但它实际上并不是同一个窗口,而是一个独立的窗口。你不能使用同样的方法隐藏单个图标,因为它们都被视为整体。
不过,你可以隐藏整个通知栏:
ShowWindow(FindWindowEx(FindWindowEx(FindWindow('Shell_TrayWnd', nil), 0, 'TrayNotifyWnd', nil), 0, 'SysPager', nil), SW_HIDE);

我想知道为什么你要在已有采纳答案的旧问题上发布答案?当然你可以这样做……只是这在这里有点不常见(至少对我来说是这样)。 - jachguate
3
对于未来(如我自己)查找此问题并希望解释为什么可以隐藏时钟但无法隐藏单个托盘图标的人。没有其他人解释过这一点。 - FSD
嗨,fsd,我好久没登录我的Stack Overflow账户了。感谢你的回答。 - Omair Iqbal

0

如果你负责运行的计算机,那么你只需右键单击图标并手动禁用它。据推测,这会在注册表中写入一些设置(使用procmon找出),因此您可以通过Active Directory自动化处理。

如果你不是负责人,也就是说,这不是你的计算机,只是某个随机计算机,而你的应用程序自愿决定隐藏它不喜欢的图标,那么没有API可以做到这一点,如果你尝试这样做,那么请滚开。什么时候隐藏图标由用户决定,而不是由你的超酷程序决定。


3
如果有人想编写一个管理系统托盘图标的应用程序,例如让用户选择何时/何地显示什么内容,那也要被封杀吗? - Sertac Akyuz
那个应用程序已经写好了。它叫做Explorer。它有一个界面,用于显示/隐藏图标以及何时/在哪里显示它们。任何不属于Explorer的增强功能都是不稳定的,因为它必须依赖于未记录的功能和技巧,如Windows搜索,以使Explorer执行其不应执行的操作。所以这是一个坏主意。不过,只要用户允许,就可以实现它,因为该应用程序可以将自身提升为管理员,然后执行所有这些肮脏的技巧。对于恶意应用程序来说,幸运的是,这种方法行不通。 - himself
2
首先,尽管较新的操作系统在这方面更加灵活,但早期的操作系统则不然。其次,自定义Shell并不罕见。我看到很多用户使用第三方软件来改变外观/行为等方面。第三,资源管理器是默认的Shell,但还有其他Shell,它们实现了系统托盘的功能...我相信我无法想到每一个有效的用途。关键是,虽然对于这里不想帮助创建恶意代码的人来说这很好,但要判断是否存在这种情况并不容易...因此,我反对你回答的语气。 - Sertac Akyuz
2
@Sertac Akyuz:非常感谢您让他认识到一些道理。 - Omair Iqbal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接