所以 window tray 的这个 bug,从 win95 一直延续到 win11?
source link: https://www.v2ex.com/t/831205
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
一个在 tray 里面的程序,如果被 kill 掉没有 gracefully 退出,那么就会一直残留在 tray
喵喵喵??? M$觉得这个是个 feature 么????
Osk 1 天前
moen 1 天前 3
至于为什么一直不加我不知道
imn1 1 天前
kkocdko 1 天前 via Android
那为什么不能隔一段时间轮询呢?难道是历史遗留问题,怕某些应用获取一次 tooltips 要花很多时间?或者某些应用依赖这种行为?
geelaw 1 天前 9
这个问题的成因是通知区域图标是程序通知任务栏创建的,崩溃时程序没有通知删除,所以不会立刻消失。
鼠标放上去会消失是因为 Explorer 会给图标对应的窗口发消息,如果窗口句柄已经无效,则会删除图标——注意窗口句柄是 USER 句柄,因此既没有计数也会复用,在极限情况下可能新程序被分配到已经崩溃程序使用过的句柄,导致新程序莫名其妙收到消息。
Explorer 崩溃重启后程序需要重新添加图标,获取这一信息的方法是注册“任务栏创建好了”消息。
为什么不能轮询——因为不存在一个“心跳”消息,也不应该随便给窗口发送消息(虽然理论上可以注册一个新名字,这样任意窗口都不会对该消息有特殊反应才对),也不应该轮询(性能问题)。
这个问题显然是可以解决的,比如任务栏上列举窗口的按钮可以对崩溃立刻作出反应,这个变化是 USER 监控,并发送 WM_SHELL_* 消息给任务栏的。然而通知区域图标并不是 USER 概念而是 shell 概念(只存在于 explorer.exe 进程中),虽然可以提升到 USER 概念实现之,估计是不值得吧( USER 是 per-session 级别的,可以容纳的句柄数量也相当有限)。
更好的解决方法是——不要崩溃。
类似的问题也存在于 Application Desktop Toolbar 。还有更多设计 bug 导致 shell 的一些部分需要两次操作才能刷新( COM categories 、shellnew 等)。
yulon 1 天前
GUI 资源一般是用户态的窗口消息管理的,他就是逼你正确处理窗口消息,不要越过 GUI 直接终止进程。
既然已经有事件的方法了,再加个轮询就显得有点脏,当然这都是设计问题,人家就是这么规定的。
ysc3839 1 天前
caocong 1 天前
coolcfan 1 天前
geelaw 1 天前 via iPhone
imn1 1 天前
dandycheung 21 小时 53 分钟前 via Android
LxnChan 19 小时 56 分钟前
@kkocdko 这个应该就是刻意没有做轮询,本身删除托盘图标的操作就是应该由程序本身发起而不是系统去做,一是性能问题二是万一当前 explorer 没有权限访问该程序(也可能是服务)就误以为该程序已经关闭甚至 explorer 直接崩溃
@CallMeReznov 草哈哈哈
ysc3839 14 小时 8 分钟前 via Android
@imn1 我没明白这是什么问题。
@dandycheung 你的说法是错的,自从出现就是 Shell Notify Icon 。这篇文章 https://devblogs.microsoft.com/oldnewthing/20030910-00/?p=42583 也给出了一些理由。
imn1 13 小时 27 分钟前
简单说,就是窗口、trayicon 、进程不是唯一对应的,例如主进程带出两个子进程,一个创建窗口,一个创建 trayicon……以此类推,还可能有第二、第三……窗口,第二、第三……trayicon ,这样检测其中某个窗口并不能确定它对应的 trayicon
FrankHB 9 小时 39 分钟前
就算不是 feature ,怕是也周知到能当作 feature 了。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK