Почему я вижу несколько значков Systray?
Я добавил значок уведомлений в свое приложение, и довольно часто я вижу до 3-х копий значка уведомления в моем systray. есть ли причина для этого?
есть способ остановить его.
Часто это сохраняется после закрытия моего приложения, пока я не перейду на systray, и systray не расширится и не разрушит snd, тогда все они исчезнут.
Ответы
Ответ 1
Это во время отладки вашего приложения? если это так, потому что сообщения, удаляющие значок из системного лотка, отправляются только тогда, когда приложение выходит из него нормально, если оно завершается из-за исключения или из-за того, что вы завершаете его из Visual Studio, значок будет оставаться до тех пор, пока вы не нажмете на него.
Ответ 2
Вы можете убить значок, используя родительское событие Window Closed. Это работает в моем приложении WPF, даже при тестировании в Visual Studio (2010 в моем случае):
parentWindow.Closing += (object sender, CancelEventArgs e) =>
{
notifyIcon.Visible = false;
notifyIcon.Icon = null;
notifyIcon.Dispose();
};
Ответ 3
Что я сделал:
-
Создайте библиотеку классов, которая обновляет системный трей.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace SystrayUtil
{
internal enum MessageEnum
{
WM_MOUSEMOVE = 0x0200,
WM_CLOSE = 0x0010,
}
internal struct RECT
{
internal int Left;
internal int Top;
internal int Right;
internal int Bottom;
internal RECT(int left, int top, int right, int bottom)
{
Left = left;
Top = top;
Right = right;
Bottom = bottom;
}
}
public sealed class Systray
{
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, IntPtr lpszWindow);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SendMessage(IntPtr hWnd, int message, uint wParam, long lParam);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool GetClientRect(IntPtr hWnd, out RECT usrTray);
public static void Cleanup()
{
RECT sysTrayRect = new RECT();
IntPtr sysTrayHandle = FindWindow("Shell_TrayWnd", null);
if (sysTrayHandle != IntPtr.Zero)
{
IntPtr childHandle = FindWindowEx(sysTrayHandle, IntPtr.Zero, "TrayNotifyWnd", IntPtr.Zero);
if (childHandle != IntPtr.Zero)
{
childHandle = FindWindowEx(childHandle, IntPtr.Zero, "SysPager", IntPtr.Zero);
if (childHandle != IntPtr.Zero)
{
childHandle = FindWindowEx(childHandle, IntPtr.Zero, "ToolbarWindow32", IntPtr.Zero);
if (childHandle != IntPtr.Zero)
{
bool systrayWindowFound = GetClientRect(childHandle, out sysTrayRect);
if (systrayWindowFound)
{
for (int x = 0; x < sysTrayRect.Right; x += 5)
{
for (int y = 0; y < sysTrayRect.Bottom; y += 5)
{
SendMessage(childHandle, (int)MessageEnum.WM_MOUSEMOVE, 0, (y << 16) + x);
}
}
}
}
}
}
}
}
}
}
-
Скопируйте dll в "%ProgramFiles%\Microsoft Visual Studio x.x\Common7\IDE\PublicAssemblies\SystrayUtil.dll"
Где x.x - номер версии Visual Studio
-
Записать макрос и сохранить его
-
Отредактируйте макрос
Добавьте ссылку на созданную dll.
Добавьте Imports SystrayUtil
в список импорта в верхней части модуля EnvironmentEvents.
Удалите все нежелательные элементы и добавьте следующий код в модуль EnvironmentEvents.
Public Sub DebuggerEvents_OnEnterDesignMode(ByVal Reason As EnvDTE.dbgEventReason) Handles DebuggerEvents.OnEnterDesignMode
Systray.Cleanup()
MsgBox("Entered design mode!")
End Sub
-
Если он работает, удалите MsgBox("Entered design mode!")
, потому что это раздражает появление окна сообщения каждый раз, когда вы возвращаетесь из сеанса отладки.
Ответ 4
Это должно работать, когда вы обычно закрываете приложение:
// in form constructor
Application.ApplicationExit += new EventHandler(this.OnApplicationExit);
private void OnApplicationExit(object sender, EventArgs e)
{
try
{
if (notifyIcon1!= null)
{
notifyIcon1.Visible = false;
notifyIcon1.Icon = null;
notifyIcon1.Dispose();
notifyIcon1= null;
}
}
catch { }
}
Когда вы останавливаете приложение от Visual Studio отключаете кнопку отладки - процесс убит и не запускается никаких событий.