2009-03-17 20 views
11

Tôi đã thêm Biểu tượng thông báo vào ứng dụng của mình và thường xuyên tôi thấy tối đa 3 bản biểu tượng thông báo trong tâm trạng của tôi. Có một lý do cho điều này?Tại sao tôi lại thấy nhiều Biểu tượng Systray?

là có cách ngăn chặn điều đó xảy ra.

Thường thì điều này vẫn còn sau khi ứng dụng của tôi đã đóng, cho đến khi tôi mose qua để systray và systray mở rộng và sụp đổ snd sau đó họ tất cả disapear.

+0

Bạn đã thêm NotifyIcon như thế nào? Trong thiết kế hoặc trong mã? – OregonGhost

+0

... và làm thế nào để bạn loại bỏ nó trong khi đóng ứng dụng? –

+0

Nhà thiết kế và tôi không xóa nó phải không? –

Trả lời

21

Đây có phải là bạn đang gỡ lỗi ứng dụng của mình không? nếu vậy điều này là do các thông báo xóa biểu tượng khỏi khay hệ thống chỉ được gửi khi ứng dụng thoát bình thường, nếu nó chấm dứt vì ngoại lệ hoặc vì bạn chấm dứt nó khỏi Visual Studio, biểu tượng sẽ vẫn còn cho đến khi bạn di chuột qua nó.

+0

Tôi ghét làm việc trên các ứng dụng có biểu tượng trong systray và ngăn chặn chúng với Visual Studio. Kết thúc với hàng chục người trong số họ nếu tôi không di chuột qua chúng. – Samuel

+6

mặc dù di chuyển cánh tay của bạn một chút trong một thời gian có thể được khỏe mạnh: p – Svish

+2

Vâng, nhưng trên một màn hình 24 inch, đó là một chuyến đi khá cho con chuột. ;) – Samuel

9

Bạn có thể giết biểu tượng bằng sự kiện Đóng của Cửa sổ mẹ. Này hoạt động trong ứng dụng WPF của tôi, ngay cả khi kiểm tra trong Visual Studio (2010 trong trường hợp của tôi):

 parentWindow.Closing += (object sender, CancelEventArgs e) => 
     { 
      notifyIcon.Visible = false; 
      notifyIcon.Icon = null; 
      notifyIcon.Dispose(); 
     }; 
2

Những gì tôi đã làm:

  1. Tạo một thư viện lớp đó cập nhật các khay hệ thống.

    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); 
                } 
               } 
              } 
             } 
            } 
           } 
          } 
         } 
        } 
    } 
    
  2. Sao chép dll để "%ProgramFiles%\Microsoft Visual Studio x.x\Common7\IDE\PublicAssemblies\SystrayUtil.dll"

    đâu xx là số phiên bản của Visual Studio

  3. Ghi macro và lưu nó

  4. Sửa vĩ mô

    Add một tham chiếu đến dll đã tạo.

    Thêm Imports SystrayUtil vào danh sách nhập ở đầu Mô-đun Môi trường.

    Hủy bỏ bất kỳ mục không mong muốn và thêm đoạn mã sau vào module EnvironmentEvents

    Public Sub DebuggerEvents_OnEnterDesignMode(ByVal Reason As EnvDTE.dbgEventReason) Handles DebuggerEvents.OnEnterDesignMode 
    Systray.Cleanup() 
    MsgBox("Entered design mode!") 
    End Sub 
    
  5. Nếu nó hoạt động loại bỏ MsgBox("Entered design mode!") vì nó gây phiền nhiễu để có một hộp thông báo xuất hiện mỗi khi bạn trở về từ một phiên gỡ lỗi.

0

này nên làm việc khi bạn thường đóng ứng dụng:

// in form's 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 { } 
} 

Khi bạn ngừng App từ nút gỡ lỗi Visual Studio dừng - quá trình này được thiệt mạng và có sự kiện nào dispose được sa thải.

Các vấn đề liên quan