我有一个(vb.net)程序,它在启动时会创建一个系统托盘图标。
当它正常退出时,系统托盘图标被正确删除。
但是,在某些情况下,例如当程序使用 MS 任务管理器“结束任务”时,程序的系统托盘图标仍然存在。
这带来了一种非常不幸的错觉,即程序在没有运行时仍在运行。
但是,在这些情况下,一旦用户将鼠标移到程序的系统托盘图标上,程序的系统托盘图标就会消失。
有没有办法确保在所有情况下都删除系统托盘图标?
我有一个(vb.net)程序,它在启动时会创建一个系统托盘图标。
当它正常退出时,系统托盘图标被正确删除。
但是,在某些情况下,例如当程序使用 MS 任务管理器“结束任务”时,程序的系统托盘图标仍然存在。
这带来了一种非常不幸的错觉,即程序在没有运行时仍在运行。
但是,在这些情况下,一旦用户将鼠标移到程序的系统托盘图标上,程序的系统托盘图标就会消失。
有没有办法确保在所有情况下都删除系统托盘图标?
当您的应用程序被终止(“结束任务”)时,您没有机会先进行整理。您的应用程序只是从内存中删除,并且没有警告(或任何阻止它的方法)。这就像你的脚下突然出现了一个洞——你没有机会先打电话回家和你的配偶或其他重要的人说再见。你刚刚走了。)
对于其他问题(在您的应用程序正确关闭后偶尔出现的“幻像图标”),有一个解决方案。我不确定它通常如何使用 .NET 解决,但是使用普通的旧 WinAPI 编程,您可以在应用程序退出时PostMessage
向窗口发送WM_NULL
消息,以导致系统托盘刷新其图标,从而导致幻像图标消失。
我从来没有在 .NET 中这样做过,但是对PInvoke的快速检查表明这样的东西应该可以工作(未经测试,但它通过 VS Express 2012 在 VB.NET 中编译和执行 - 我显然没有编写一个实际的系统托盘应用程序测试它是否有效,因为故意导致“幻像图标”出现是困难的):
Private Declare Function PostMessage _
Lib "coredll.dll" (ByVal hWnd As IntPtr, _
ByVal Msg As Integer, _
ByVal wParam As Integer, _
ByVal lParam As Integer) As IntPtr
Private Sub Form1_FormClosed(sender As Object, _
e As FormClosedEventArgs) _
Handles MyBase.FormClosed
Const WM_NULL As Integer = &H0
PostMessage(Me.Handle, WM_NULL, 0, 0)
End Sub
请注意,使用它非常重要,PostMessage
而不是SendMessage
为此目的。第一个只是将消息放入消息队列并返回,而第二个等待响应(您的应用程序不会在那里发送一个响应,因为它已经在关闭过程中)。
注意 #2:您可能需要在Form1_FormClosing
处理程序中执行此操作,而不是FormClosed
; 正如我所说,我没有一个系统托盘应用程序来测试用于发布消息的正确位置的时间。