Skip to content

Commit 58c3771

Browse files
committed
Fix issue: The program exits,but the NotifyIcon still exists
1 parent 0c8d77f commit 58c3771

1 file changed

Lines changed: 100 additions & 11 deletions

File tree

src/WPFDevelopers.Shared/Controls/NotifyIcon/NotifyIcon.cs

Lines changed: 100 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,15 @@ public NotifyIcon()
103103
_TrayWndProc = WndProc_CallBack;
104104
_TrayWndMessage = "TrayWndMessageName";
105105
_TrayMouseMessage = (int)WM.USER + 1024;
106-
Start();
107106
if (Application.Current != null)
108107
{
108+
Application.Current.Exit += OnCurrent_Exit;
109109
WPFDevelopers.Resources.ThemeChanged += Resources_ThemeChanged;
110-
Application.Current.Exit += (s, e) => Dispose();
111110
}
111+
Start();
112112
NotifyIconCache = this;
113113
}
114+
114115
static NotifyIcon()
115116
{
116117
DataContextProperty.OverrideMetadata(typeof(NotifyIcon), new FrameworkPropertyMetadata(DataContextPropertyChanged));
@@ -274,7 +275,8 @@ private void DispatcherTimerTwinkTick(object sender, EventArgs e)
274275
_iconHandle = _iconHandle != IntPtr.Zero ? IntPtr.Zero : _tempIconHandle;
275276
ChangeIcon(false, _iconHandle);
276277
}
277-
private static void Current_Exit(object sender, ExitEventArgs e)
278+
279+
private void OnCurrent_Exit(object sender, ExitEventArgs e)
278280
{
279281
s_NotifyIcon?.Dispose();
280282
s_NotifyIcon = default;
@@ -293,20 +295,54 @@ public bool Start()
293295

294296
public bool Stop()
295297
{
296-
//销毁窗体
298+
if (_dispatcherTimerTwink != null)
299+
{
300+
_dispatcherTimerTwink.Stop();
301+
_dispatcherTimerTwink = null;
302+
}
303+
304+
if (Thread.VolatileRead(ref _IsShowIn) == 1)
305+
{
306+
Hide();
307+
}
308+
309+
if (_hIcon != IntPtr.Zero)
310+
{
311+
User32Interop.DestroyIcon(_hIcon);
312+
_hIcon = IntPtr.Zero;
313+
}
314+
315+
if (_tempIconHandle != IntPtr.Zero)
316+
{
317+
User32Interop.DestroyIcon(_tempIconHandle);
318+
_tempIconHandle = IntPtr.Zero;
319+
}
320+
321+
if (_iconHandle != IntPtr.Zero)
322+
{
323+
User32Interop.DestroyIcon(_iconHandle);
324+
_iconHandle = IntPtr.Zero;
325+
}
326+
297327
if (_TrayWindowHandle != IntPtr.Zero)
328+
{
298329
if (User32Interop.IsWindow(_TrayWindowHandle))
330+
{
299331
User32Interop.DestroyWindow(_TrayWindowHandle);
332+
}
333+
_TrayWindowHandle = IntPtr.Zero;
334+
}
300335

301-
//反注册窗口类
302336
if (!string.IsNullOrWhiteSpace(_TrayWndClassName))
303-
User32Interop.UnregisterClassName(_TrayWndClassName, Kernel32Interop.GetModuleHandle(default));
337+
{
338+
User32Interop.UnregisterClassName(_TrayWndClassName,
339+
Kernel32Interop.GetModuleHandle(default));
340+
}
304341

305-
//销毁Icon
306-
if (_hIcon != IntPtr.Zero)
307-
User32Interop.DestroyIcon(_hIcon);
342+
Thread.VolatileWrite(ref _IsShowIn, 0);
308343

309-
Hide();
344+
_contextContent = null;
345+
_icon = null;
310346

311347
return true;
312348
}
@@ -602,10 +638,15 @@ private bool Hide()
602638

603639
Thread.VolatileWrite(ref _IsShowIn, 0);
604640

641+
bool result;
605642
lock (this)
606643
{
607-
return Shell32Interop.Shell_NotifyIcon(NotifyCommand.NIM_Delete, ref _NOTIFYICONDATA);
644+
result = Shell32Interop.Shell_NotifyIcon(NotifyCommand.NIM_Delete, ref _NOTIFYICONDATA);
608645
}
646+
647+
_NOTIFYICONDATA = default;
648+
649+
return result;
609650
}
610651

611652
private IntPtr WndProc_CallBack(IntPtr hwnd, WM msg, IntPtr wParam, IntPtr lParam)
@@ -719,11 +760,59 @@ protected virtual void Dispose(bool disposing)
719760
if (!disposedValue)
720761
{
721762
if (disposing)
763+
{
764+
if (_dispatcherTimerTwink != null)
765+
{
766+
_dispatcherTimerTwink.Stop();
767+
_dispatcherTimerTwink.Tick -= DispatcherTimerTwinkTick;
768+
_dispatcherTimerTwink = null;
769+
}
770+
771+
if (Application.Current != null)
772+
{
773+
WPFDevelopers.Resources.ThemeChanged -= Resources_ThemeChanged;
774+
}
775+
776+
if (_contextContent != null)
777+
{
778+
_contextContent.IsOpen = false;
779+
_contextContent.Child = null;
780+
_contextContent = null;
781+
}
782+
722783
Stop();
784+
}
785+
786+
if (_hIcon != IntPtr.Zero)
787+
{
788+
User32Interop.DestroyIcon(_hIcon);
789+
_hIcon = IntPtr.Zero;
790+
}
791+
792+
if (_tempIconHandle != IntPtr.Zero)
793+
{
794+
User32Interop.DestroyIcon(_tempIconHandle);
795+
_tempIconHandle = IntPtr.Zero;
796+
}
797+
798+
if (_iconHandle != IntPtr.Zero)
799+
{
800+
User32Interop.DestroyIcon(_iconHandle);
801+
_iconHandle = IntPtr.Zero;
802+
}
803+
804+
if (ReferenceEquals(this, NotifyIconCache))
805+
{
806+
NotifyIconCache = null;
807+
}
723808

724809
disposedValue = true;
725810
}
726811
}
812+
~NotifyIcon()
813+
{
814+
Dispose(false);
815+
}
727816
}
728817

729818
public enum NotifyIconInfoType

0 commit comments

Comments
 (0)